P1842 奶牛玩杂技
题目背景
Farmer John 养了N(1<=N<=50,000)头牛,她们已经按1~N依次编上了号。FJ所不知道的是,他的所有牛都梦想着从农场逃走,去参加马戏团的演出。可奶牛们很快发现她们那笨拙的蹄子根本无法在钢丝或晃动的的秋千上站稳(她们还尝试过把自己装在大炮里发射出去,但可想而知,结果是悲惨的) 。最终,她们决定练习一种最简单的杂技:把所有牛都摞在一起, 比如说, 第一头牛站在第二头的身上, 同时第二头牛又站在第三头牛的身上...最底下的是第 N头牛。
题目描述
每头牛都有自己的体重以及力量,编号为 i 的奶牛的体重为
W_i(1<=W_i<=10,000),力量为 S_i(1<=S_i<=1,000,000,000)。
当某头牛身上站着另一些牛时它就会在一定程度上被压扁,我们不妨把它被压扁的程度叫做它的压扁指数。对于任意的牛,她的压扁指数等于摞在她上面的所有奶牛的总重(当然不包括她自己)减去它的力量。奶牛们按照一定的顺序摞在一起后, 她们的总压扁指数就是被压得最扁的那头奶牛的压扁指数。
你的任务就是帮助奶牛们找出一个摞在一起的顺序,使得总压扁指数最小。
输入输出格式
输入格式:
第一行:N
接下来N行,每行两个数:Wi和Si
输出格式:
最小总压扁指数
输入输出样例
3 10 3 2 5 3 3
2
这是一道贪心题。
首先我们猜测,重量大的牛在下面。但很明显不行。
(1,5) -5
(2,1) 0
如果重量为1,力量为5的牛在上面,那么这里 他的最小总压扁指数就是0。
(2,1) -1
(1,5) -3
如果重量为2,力量为1的牛在上面,那么这里 他的最小总压扁指数就是-3。 很明显这里是正解,上面是错误的。
那么按重量来排序不行,就按力量?
两头牛(10,3)与(1,2)。如果按照力量来排序,那么也是错误的。
问题来了,怎么破。
其实应该按照 重量+力量 来进行排序。
重量+力量越大,牛就越在下面。
这其实是能够用数学方法证明的,但在下数学不好。。这种贪心题,多刷几道,就能看出来该怎么做了。
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 //每个牛的w重量和s力量 6 struct Node{ 7 int w, s; 8 }cow[50005]; 9 //比较函数 重量+力量 10 int cmp(Node a, Node b) 11 { 12 return (a.w+a.s > b.w+b.s); 13 } 14 //交换函数 15 void swapp(int &a, int &b) 16 { 17 int t; 18 t = a; 19 a = b; 20 b = t; 21 } 22 23 int main() 24 { 25 int n, sum(0), maxx(-999999999), tmp; 26 scanf("%d", &n); 27 for(int i=0; i<n; i++) 28 scanf("%d%d", &cow[i].w, &cow[i].s); 29 //对每个牛依据w+s,从大到小排序 30 sort(cow, cow+n, cmp); 31 //0是最底端 n是顶端 32 //从n开始计算每个牛的压扁指数 33 for(int i=n-1; i>=0; i--) 34 { 35 tmp = sum - cow[i].s; //sum是这头牛上面的牛的重量之和 36 if(tmp > maxx) //maxx存放总压扁指数 37 swapp(tmp, maxx); 38 sum += cow[i].w; //记得加上这头牛的重量 39 } 40 printf("%d", maxx); 41 return 0; 42 }