题意:N头牛,每头牛有一个重量和一个力量,每头牛承受的YaLi为在它上面的所有牛的重量之和减去它的力量,要求最小化最大YaLi
题解:
贪心
重量+力量越大的放在越下面
证明:
假设最优放置,取相邻两头牛A(w1,s1),B(w2,s2),sum表示第一头牛所承受的重量
A的代价:a=sum-s1,B的代价:b=sum+w1-s2
若两者交换,A的代价:a'=sum+w2-s1,B的代价:b'=sum-s2
由:b<=a' -> w1-s2<=w2-s1 -> w1+s1<=w2+s2
总结:
注意贪心的性质:局部最优->全局最优
所以找贪心策略的时候先要分析局部情况,继而推广到全局
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
const int N = 50010;
int pre[N];
struct Node {
int x,y,z;
bool operator < (const Node &a) const {
return x+y<a.x+a.y;
}
}p[N];
int gi() {
int x=0,o=1; char ch=getchar();
while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
if(ch=='-') o=-1,ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return o*x;
}
int main() {
int n=gi(),ans=-1<<30;
for(int i=1; i<=n; i++) {
int x=gi(),y=gi(),z=x+y;
p[i]=(Node){x,y,z};
}
sort(p+1,p+n+1);
for(int i=1; i<=n; i++) {
pre[i]=pre[i-1]+p[i].x;
}
for(int i=1; i<=n; i++) {
ans=max(ans,pre[i-1]-p[i].y);
}
printf("%d", ans);
return 0;
}