一、题目
题目背景
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
二、思路
贪心算法。
问题在于,怎样贪心呢?
按照重量排序?最重的放下面?
显然错误。
按照力量排序?最有力量的放下面?
也不行。
动态规划?走一边,不会!
所以,我们的贪心算法是,按照重量与力量的和排序,和最大的放下面!
三、注意
- ans可能为负
- 变量要开long long
- 奶牛的顺序
我因为这些东西错了三次!
四、我的C++源代码
#include<iostream>
#include<algorithm>
#include<cstdio>
typedef long long ll;
using namespace std;
inline int read(void)//读入优化
{
int f = 1, x = 0; char ch = getchar();
while (ch<'0' || ch>'9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0'&&ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return f*x;
}
const int maxn = 50005;
struct Node {
int w, s, he;
}niu[maxn];
int n, sum;
bool cmp(const Node&x, const Node&y) {
return x.he < y.he;
}//按照力量和重量排序
int max(int a, int b)
{
return a > b ? a : b;
}
int main()
{
n = read();
for (int i = 1; i <= n; i++) {
niu[i].w = read();
niu[i].s = read();
niu[i].he = niu[i].w + niu[i].s;
sum += niu[i].w;
}
ll ans = -1e9;//ans有可能为负
sort(niu + 1, niu + n + 1, cmp);//按照力量和重量排序
for (int i = n; i >= 1; i--) {
sum -= niu[i].w;//总和
ans = max(sum - niu[i].s, ans);
}
printf("%d\n", ans);
return 0;
}
大功告吉!!!不要Ctrl+C哦。