bzoj3174: [Tjoi2013]拯救小矮人
被欧老师DDDDDDDDDDDDDDDDDDD飞飞飞飞飞飞飞飞飞飞飞了了了了了了了了了了了了
心态爆炸打打水。。。。贪心啊,玄学啊
就是每次把最挫的挑出来D飞。。。
——————————————————————————————————————————————————————
upd:我以前就是一sb。。。
矮人按a+b的小到大排序
首先假如a1<a2且b1<b2的话,明显尽量让1先跑掉
假如a1+b1<a2或b2,同理也是让1先跑
考虑在剩下的情况中,假设顺序已经排好了,那么假如交换1和2的位置,开始左右的不同部分为a1+b1+a2,b2+a2,后来是a2+b2+a1,b1+a1
假如两个都可能跑掉,那么我们按a+b的小到大排序,更有可能两个跑掉(b2+a2>b1+a1)
否则,先让前一个尝试,失败了再转入后一个状态,也不会亏
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; struct node { int x,y; }a[2100]; bool cmp(node n1,node n2){return (n1.x+n1.y)<(n2.x+n2.y);} int f[2100]; int main() { int n; scanf("%d",&n); memset(f,-1,sizeof(f));f[0]=0; for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y),f[0]+=a[i].x; sort(a+1,a+1+n,cmp); int H,tot=0; scanf("%d",&H); for(int i=1;i<=n;i++) { for(int j=tot;j>=0;j--) { if(f[j]+a[i].y>=H)f[j+1]=max(f[j+1],f[j]-a[i].x); if(f[tot+1]!=-1)tot++; } } printf("%d\n",tot); return 0; }
pain and happy in the cruel world.