poj3045.cpp

来源:互联网 发布:藏族怎么看中国知乎 编辑:程序博客网 时间:2024/04/28 09:11

题目表面是最大值最小化的问题,但由于顺序不确定,不适宜二分,显然《挑战程序设计竞赛》出现了瑕疵。

但肯定能用已有知识解决。

只需按照w+s从小到大排序,证明如下:

可以利用反证法。> > 1)A站在B的上方,A的承重为m,B的承重为m + A.w。> 2)调换AB的位置,那么B的承重为m,A的承重为m + B.w。> > 如果A.s + A.w < B.s + B.w,> 并且第一种方法不可行,即 B.s < m + A.w,> 那么第二种方法,A.s < (B.s) + B.w - A.w < (m + A.w) + B.w - A.w = m + B.w。> 所以第二种方法肯定也不可行。> > 另外:来证明这种方法能最小化risk:> 如果A.s + A.w < B.s + B.w:> A在上方时,riskA1 = m - A.s,  riskB1 = m + A.w - B.s> B在上方时,显然riskA2 > riskA1;> 还可以证明,riskA2 = m + B.w - A.s > m + A.w - B.s = riskB1。> 所以A站在上方时能最小化risk。

参考程序:

#include<cstdio>#include<algorithm>#define maxn 51000using namespace std;struct Cow{int w,s;bool operator < (Cow b) const {return w+s<b.w+b.s;}};Cow cow[maxn];int main(){int n;scanf("%d",&n);for (int i=0;i<n;i++)scanf("%d%d",&cow[i].w,&cow[i].s);sort(cow,cow+n);int ans=-0x7f7f7f7f,sum=0;//不理解为什么ans可以是负数,原来设的是0,WA了。。改了后ACfor (int i=0;i<n;i++){ans=max(ans,sum-cow[i].s);sum+=cow[i].w;}printf("%d",ans);return 0;}


0 0
原创粉丝点击