bzoj千题计划208:bzoj3174: [Tjoi2013]拯救小矮人
http://www.lydsy.com/JudgeOnline/problem.php?id=3174
按a+b从小到大排序,a+b小的在上面,先考虑让它逃出去
正确性不会证
感性理解一下,最后一个可以达到的最高高度为a+b,显然它越大越能逃出去
f[i][j] 表示前i个逃出去j个后,剩余的最大高度
如果f[j]+b[i]>=H,f[j+1]=max(f[j]-a[i])
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define N 2001 struct node { int a,b; }e[N]; int f[N]; void read(int &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } } bool cmp(node p,node q) { return p.a+p.b<q.a+q.b; } int main() { int n; read(n); int sum=0; memset(f,-1,sizeof(f)); f[0]=0; for(int i=1;i<=n;++i) { read(e[i].a);read(e[i].b); f[0]+=e[i].a; } int h; read(h); sort(e+1,e+n+1,cmp); int ans=0; for(int i=1;i<=n;++i) { for(int j=ans;j>=0;--j) if(f[j]+e[i].b>=h) f[j+1]=max(f[j+1],f[j]-e[i].a); if(f[ans+1]>=0) ans++; } cout<<ans; }