洛谷 P1842 奶牛玩杂技 题解

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

输出格式

最小总压扁指数

输入输出样例

输入 #1

3
10 3
2 5
3 3

输出 #1

2

【前缀知识】

贪心
正常我们看到的贪心是只有一个变量的
但是这道题目有两个
奶牛的重量和奶牛的力气
用贪心的思维来思考一下
重量大的是不是应该放的更靠下?
放的越靠下他的大重量影响的奶牛就越少
所以 \(W_i\) 越大就越要越往下放
那么,奶牛力气越大的就越往下放是不是也是类似的道理?
力气越大能够支持的重量越多,
所以收重量的影响就越小,
为了让最大值最小就应该让力气大的去承受更多的重量
因为一个力气小的 \(S_1\) 和一个 力气大的 \(S_2\) 去承受同样的重量
\(W - S_1\) < \(W - S_2\)
所以力气越大的就应该越往下放
这个时候就有两个需要贪心的了

【证明过程】

假设只有两只奶牛,一只奶牛的重量为 \(W_1\) ,力气为 \(S_1\)
另一只奶牛的重量为 \(W_2\) ,力气为 \(S_2\)
如果前者在下
压扁指数即为 \(W_2 - S_1\)
如果后者在下
压扁指数即为 \(W_1 - S_2\)
假设前者在下更优
即为前者在下压扁指数更小
那么
\(W_2 - S_1 < W_1 - S_2\)
移项的
\(W_2 + S_2 < W_1 + S_1\)
这个时候是处于前者在下更优的情况下
所以得出结论
\(W_i + S_i\)越大就应该越往下放

【引出】

这只是有两只奶牛的情况
可以通过这个类比出多个奶牛的情况所以
这个结论适用

【完整代码】

#include<iostream>
#include<cstdio>
#include<algorithm> 

using namespace std;
const int Max = 50005;
struct node
{
	int w,s;
}a[Max];
bool cmp(const node x,const node y)
{
	return x.w + x.s < y.w + y.s;
}
int M = 0x7fffffff; 
int main()
{
	int n;
	cin >> n;
	for(int i = 1;i <= n;++ i)
		cin >> a[i].w >> a[i].s,M = min(M,a[i].s);//如果只有一个的话那就输出他的力气的负数所以这里需要找出最大的力气 
	M = -M;
	sort(a + 1,a + 1 + n,cmp);
	int tot = a[1].w;
	for(int i = 2;i <= n;++ i)
	{
		M = max(M,tot - a[i].s);
		tot += a[i].w;
	}
	cout << M << endl;
	return 0;
}
posted @ 2019-10-07 09:00  acioi  阅读(411)  评论(0编辑  收藏  举报