题解【[USACO05NOV]奶牛玩杂技】

\[
\texttt{Description}
\]

有 \(n\) 头牛,每头牛都有自己的体重 \(W_i\) 和力量 \(S_i\) 。

将这 \(n\) 头牛摞在一起,每头牛的压扁指数定义为:压在该牛上面的牛的体重之和 \(-\) 该牛力量 。

您需要找到一种摞牛方案,使得压扁指数最大的牛的压扁指数最小。

求这个压扁指数。
\[
\texttt{Solution}
\]

  • 微扰(邻项交换)证明贪心好题。
  • 考虑任意一个摞牛方案,设该摞牛方案中,从顶端往底端数的第 \(i\) 头牛的体重为 \(W_i\) ,力量为 \(S_i\) 。
  • 记 \(Z_i=\sum\limits_{j=1}\limits^{i}W_j\)(前 \(i\) 头牛体重和)。
  • 我们考虑任意一个邻项,考虑交换:
第 \(i\) 头牛 第 \(i+1\) 头牛
交换前压扁指数 \(Z_{i-1}-S_i\) \(Z_{i-1}+W_i-S_{i+1}\)
交换后压扁指数 \(Z_{i-1}-S_{i+1}\) \(Z_{i-1}+W_{i+1}-S_i\)
  • 我们发现需要比较这两个式子的值:

\[
\max(Z_{i-1}-S_i,Z_{i-1}+W_i-S_{i+1}) \\ \max(Z_{i-1}-S_{i+1},Z_{i-1}+W_{i+1}-S_i)
\]

  • 式子内部减去 \(Z_{i-1}\) ,得:

\[
\max(-S_i,W_i-S_{i+1}) \\ \max(-S_{i+1},W_{i+1}-S_i)
\]

  • 式子内部加上 \(S_i+S_{i+1}\) ,得:

\[
\max(S_{i+1},W_i+S_i) \\ \max(S_i,W_{i+1}+S_{i+1})
\]

  • 注意到 \(W\) 为正整数,所以有 \(S_i \leq W_i+S_i\) ,\(S_{i+1} \leq W_{i+1}+S_{i+1}\) 。
  • 也就是说当 \(S_{i+1} = \max(S_{i+1},W_i+S_i)\) 时,也定不会比 \(\max(S_i,W_{i+1}+S_{i+1})\) 大,另一式子同理。
  • 故可以转化为比较这两个式子的值:

\[
W_i+S_i \\ W_{i+1}+S_{i+1}
\]

  • 当 \(W_i+S_i \leq W_{i+1}+S_{i+1}\) 时,上式 \(\leq\) 下式,则交换前定不比交换后优。
  • 当 \(W_i+S_i \geq W_{i+1}+S_{i+1}\) 时,上式 \(\geq\) 下式,则交换后定不比交换前劣。
  • 我们将满足 \(W_i+S_i > W_j+S_j\) ,\(i<j\) 的点对 \((i,j)\) 视为一个逆序对,显然,在任意局面下,增加逆序对的数量都不会使整体结果变优,减少逆序对的数量都不会使整体结果变差。
  • 根据冒泡排序,在任意局面下,都可通过邻项交换使得该序列的逆序对数量变 \(0\) ,当逆序对数量为 \(0\) 时,实际上就是将这 \(n\) 头牛以 \(W_i+S_i\) 为关键字从小到大排序。
  • 至此我们就有一个贪心策略:将这 \(n\) 头牛以 \(W_i+S_i\) 为关键字从小到大排序尽管这个贪心策略很玄学。
  • 排好序,按题目描述说的一样算出答案即可。
  • \(\mathcal{O(n \log n)}\) 。

\[
\texttt{Code}
\]

#include<cstdio>
#include<algorithm>

#define RI register int

using namespace std;

inline int read()
{
    int x=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-f;s=getchar();}
    while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
    return x*f;
}

const int N=50010;

int n;

struct Cow{
    int W,S;
}a[N];

bool cmp(Cow a,Cow b)
{
    return a.W+a.S<b.W+b.S;
}

long long ans=-0x3f3f3f3f;

int main()
{
    n=read();

    for(RI i=1;i<=n;i++)
        a[i].W=read(),a[i].S=read();

    sort(a+1,a+1+n,cmp);

    long long sum=0;
    for(RI i=1;i<=n;i++)
    {
        ans=max(ans,sum-a[i].S);
        sum+=a[i].W;
    }

    printf("%lld\n",ans); 

    return 0;
}

\[
\texttt{Thanks} \ \texttt{for} \ \texttt{watching}
\]

原文地址:https://www.cnblogs.com/cjtcalc/p/12369834.html

时间: 2024-12-16 14:47:20

题解【[USACO05NOV]奶牛玩杂技】的相关文章

P1842 奶牛玩杂技

P1842 奶牛玩杂技 这道题目知道结论是比较好写的,关键是结论是怎样推出来的. 我们先只考虑相邻的两个奶牛,设这两个奶牛为 \(a\) 和 \(b\) ,这两个奶牛上面的奶牛总重量为 \(W\) ,所以我们考虑 \(a\) 在上面的情况和 \(b\) 在上面的情况. \(a\) 在上面的情况: \(a\) 的压扁指数为 \(W-S_a\) , \(b\) 的压扁指数为 \(W+W_a-S_b\) . \(b\) 在上面的情况: \(b\) 的压扁指数为 \(W-S_b\) , \(a\) 的压

关于10月23日#10的六道题的心得与感悟

今天连着#9做到了#10.先说最近的#10吧. 第一题: 暴力模拟,没有什么算法或思想可言.就是锻炼代码能力,提高对细节的注意. 第二题: 一开始直接想到了前缀和,算出前缀和后,枚举起点终点,算出差值,判断是否能整除.结果可想而知,直接TLE.后来抓耳挠腮,几番思索无果,果断看题解,将前缀和加以处理,先用前缀和模上d,在遍历一次数组,当Mod == 0 或 当前Mod在之前出现过一次 , 就在结果上+1. 第三题:分饼.有f+1个人分n块饼吃,每块饼都是圆柱体,高全为1,给出每块饼的半径.求每个

UVA11427 Expect the Expected

题意:每盘游戏赢的概率,一天玩n盘,如果赢得比例超过p就会停止,求平均玩几天 题解:每天玩的赢得概率相等,只要求一天的概率即可,期望可以极限算出 还有一种做法,每天是独立的,第1天输的期望是1概率是Q,第一天赢得概率是(1-Q)就到第二天,第二天期望是e,加上第一天,就是e+1,全期望公式得e = Q*e+(1-Q)*e #include <bits/stdc++.h> #define maxn 110 #define ll long long using namespace std; dou

usaco月赛,2017.1总结

T1:跳舞的奶牛 大致题意:一个体积为k的舞台能够同时容纳k只奶牛一起跳舞,他们每头奶牛的跳舞时间不同,如果有一只奶牛跳完了第k+1头奶牛就会立刻上场跳舞,当所有奶牛跳完舞以后我们认为这次表演结束.现在给出奶牛个数,最多用时,每头奶牛的跳舞时间.求舞台最小为多大. 思路:本来写了个程序以为这道题很简单,刚开始排一下序然后就行了,结果交了以后发现只过了五组,然后才发现这道题不能改变顺序(所以说为什么我改变顺序了还是能过五组,usaco的数据也好水......),所以说我想到了堆,然后就用堆写了一下

BZOJ 1025 [SCOI2009]游戏

之前找LLJ大佬推荐水题的时候让我做这个,然后不出意料的我不会. 日常抄题解. 手玩几组数据发现它N个数可以分成多个组,每个组为一个循环,他们的LCM就是最后的层数. 预处理出n以内的所有质数,我们可以把n分解成p1^a1+p2^a2+p3^a3...不同的p之间的lcm数可以直接相乘,我们用dp递推地算答案,dp[i][j表示前i个质数和为j的lcm数,然后就可以DP了. 最后统计答案要把0~n的dp[p[0]][i]加起来,因为每个数可以单成一组. #include<cstdio> #in

Graham&#39;s Scan法求解凸包问题

概念 凸包(Convex Hull)是一个计算几何(图形学)中的概念.用不严谨的话来讲,给定二维平面上的点集,凸包就是将最外层的点连接起来构成的凸多边型,它能包含点集中所有点的.严谨的定义和相关概念参见维基百科:凸包. 这个算法是由数学大师葛立恒(Graham)发明的,他曾经是美国数学学会(AMS)主席.AT&T首席科学家以及国际杂技师协会(IJA)主席.(太汗了,这位大牛还会玩杂技~) 问题 给定平面上的二维点集,求解其凸包. 过程 1. 在所有点中选取y坐标最小的一点H,当作基点.如果存在多

矩阵乘法专题2——bzoj 1706 [usaco2007 Nov] relays 奶牛接力跑 题解

转载请注明:http://blog.csdn.net/jiangshibiao/article/details/24960651 [原题] 1706: [usaco2007 Nov]relays 奶牛接力跑 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 340  Solved: 162 [Submit][Status] Description FJ的N(2 <= N <= 1,000,000)头奶牛选择了接力跑作为她们的日常锻炼项目.至于进行接力

【题解】黑白奶牛

题目描述 有N只奶牛从左往右排成一行,编号是1至N.这N只奶牛当中,有一些奶牛是黑色的,其余的是白色的. color[i]表示第i只奶牛的颜色,如果color[i]=0则表示第i头奶牛是黑色的,如果color[i]=1则表示第i头奶牛是白色的. 六一奶牛儿童节快到了,农场主Farmer John要从这N头奶牛当中,挑选尽可能多的奶牛去参加晚会. Farmer John挑选奶牛的原则是:挑选编号是连续的一段奶牛,这一段奶牛的颜色必须全部是白色的. Farmer John有一个魔法棒,每用一次魔法棒

【题解】幸运奶牛

题目描述 有N头奶牛从左往右排成一行,编号是1至N.如果某头奶牛的编号是2的倍数或者是3的倍数,那么这头奶牛就是幸运奶牛.这N头奶牛中,总共有多少头奶牛是幸运奶牛? 输入输出格式 输入格式 一行,一个整数N. 输出格式 一行,一个整数,表示幸运奶牛的数量. 输入输出样例 输入样例 10 输出样例 7 说明 数据规模 对于70%的数据,1≤N≤10000. 对于100%的数据,1≤N≤2000000000. 题解 小学奥数,直接上代码. #include <cstdio> int main()