题意: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; }