标签:bzoj3174 tjoi2013 拯救小矮人 贪心 动规
转载请注明出处~~~thx~http://blog.csdn.net/vmurder/article/details/42879403
呃、
就是先贪心排序一下,然后做动规。
题解:
首先我们考虑两个人之间的先后离开顺序:
肯定我们希望逃生能力(权值a+权值b)强的人后跑,因为这样更可能多跑
(这里不妨考虑:我们希望整个塔的逃生能力更强,而塔的逃生能力就是所有人的身高+max{手长})。
然后这样我们可以按照逃跑顺序排个序,方便接下来的动规。
(不要太较真~~我也不是特别“有理有据”,只是感性地YY了一下这个证明)
逃跑顺序出来以后,我们设f[i]为所有人中跑出去i个人后塔的最高高度(不算max{手长})
这里再感性地想一下,就是在同等的人逃出去的前提下,如果我们还想人逃出去,那么这个总的逃生能力肯定是要尽量大的,而逃跑顺序已经有上述的贪心来保证,那么要提高将要逃跑的这个人的逃跑能力,方法就是在底下垫人,肯定就是越高越好~~
差不多了,觉得不够的可以自己再随便查查网上题解,还是有那么两篇的。~·~。
代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 101000 using namespace std; struct KSD { int x,y; bool operator < (const KSD &a)const{return x+y<a.x+a.y;} }ksd[N]; int n,m,ans,f[N]; int main() { int i,j; scanf("%d",&n); memset(f,-1,sizeof(f)),f[0]=0; for(i=1;i<=n;i++)scanf("%d%d",&ksd[i].x,&ksd[i].y),f[0]+=ksd[i].x; sort(ksd+1,ksd+n+1); scanf("%d",&m); for(i=1;i<=n;i++) { for(j=ans;j>=0;j--) { if(ksd[i].y+f[j]>=m)f[j+1]=max(f[j+1],f[j]-ksd[i].x); if(f[ans+1]>=0)ans++; } } printf("%d\n",ans); return 0; }
【BZOJ3174】【Tjoi2013】拯救小矮人 贪心+动规。
标签:bzoj3174 tjoi2013 拯救小矮人 贪心 动规
原文地址:http://blog.csdn.net/vmurder/article/details/42879403