POJ 3628 Bookshelf 2 0-1背包
传送门:http://poj.org/problem?id=3628
题目看了老半天,牛来叠罗汉- -|||和书架什么关系啊。。
大意是:一群牛来叠罗汉,求超过书架的最小高度。
0-1背包的问题,对于第i只牛可以放或者不放。然后最后求出大于书架高度的,减去书架高度即可。
也可以倒着来看。背包的容量为牛总的高度-书架的高度,求不超过这个容量的最大值,最后容量-这个值就是答案了。(推荐)
还可以DFS..
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN=1000000+5; int H[22],f[MAXN]; int main() { int N,B; while(~scanf("%d%d",&N,&B)) { memset(f,0,sizeof(f)); int sum=0; for(int i=1;i<=N;i++) { scanf("%d",&H[i]); sum+=H[i]; } for(int i=1;i<=N;i++) { for(int j=sum;j>=H[i];j--) { f[j]=max( f[j] , f[j-H[i]]+H[i] ); } } for(int i=B;i<=sum;i++) if(f[i]==i) { printf("%d\n",f[i]-B); break; } } }
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN=1000000+5; int H[22],f[MAXN]; int main() { int N,B; while(~scanf("%d%d",&N,&B)) { memset(f,0,sizeof(f)); int sum=0; for(int i=1;i<=N;i++) { scanf("%d",&H[i]); sum+=H[i]; } int contain=sum-B; for(int i=1;i<=N;i++) { for(int j=contain;j>=H[i];j--) { f[j]=max( f[j] , f[j-H[i]]+H[i] ); } } printf("%d\n",contain-f[contain]); } }
DFS:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int INF=9999999; int H[22]; bool visit[22]={0}; int N,B; int ans; void dfs(int cur , int sum) { if(sum >=ans) return; if(cur==N) { if(sum>=B) ans=sum; return; } dfs(cur+1,sum); dfs(cur+1,sum+H[cur]); } int main() { while(~scanf("%d%d",&N,&B)) { ans=INF; for(int i=0;i<N;i++) scanf("%d",&H[i]); dfs(0,0); printf("%d\n",ans-B); } }
新 blog : www.hrwhisper.me