01背包
hdu2955 Robberies
需要找到背包的容量。
有两个选择
1.能获得的最大金额
每个银行价值≤100,最多100家银行,所以能获得的最大金额为10000(不考虑风险)
int v[10000] ;
2.逃脱的概率。
最终逃脱的概率为在每一个银行都不被抓,即所有的逃脱概率(1-P[i])相乘。
把概率放大一百倍之后作为背包容量?
以金额作为背包,概率作为价值。满足dp[i]>=P的最后一个元素的下标就是答案
多重背包
二进制优化
#include<stdio.h> int main() { int N,n,sum; while(scanf("%d",&N),N) { n=1,sum=0; while(n<=N/2) { printf("%d ",n); sum+=n; //为最后一个数字做准备 n*=2; //double } n=N-sum; printf("%d\n",n); } return 0; }
hdu2844
给出N种物品,第i种有n[i]个,体积为v[i]
用这些物品能组成多少种体积(即题目中的价格)
#include<iostream> using namespace std; int dp[100001],v[101],n[101]; int main() { int N,M,num,sum,i,j; while(scanf("%d%d",&N,&M),N+M) { for(i=1;i<=N;i++) scanf("%d",&v[i]); for(i=1;i<=N;i++) scanf("%d",&n[i]); memset(dp,0,sizeof(dp)); for(i=1;i<=N;i++) { sum=0,num=1; while(num<=n[i]/2) { for(j=M;j>=num*v[i];j--) { if(dp[j]<dp[j-num*v[i]]+v[i]*num) dp[j]=dp[j-num*v[i]]+v[i]*num; } sum+=num; num*=2; } num=n[i]-sum; for(j=M;j>=num*v[i];j--) { if(dp[j]<dp[j-num*v[i]]+v[i]*num) dp[j]=dp[j-num*v[i]]+v[i]*num; } } for(sum=0,i=1;i<=M;i++) if(dp[i]==i) sum++; printf("%d\n",sum); } return 0; }
hdu2191
#include<iostream> using namespace std; int main() { int T,N,M,dp[101],v[101],p[101],n[101],i,j,num,sum; scanf("%d",&T); while(T--) { scanf("%d%d",&N,&M); memset(dp,0,sizeof(dp)); for(i=1;i<=M;i++) { scanf("%d%d%d",&v[i],&p[i],&n[i]); num=1,sum=0; while(num<=n[i]/2) { for(j=N;j>=num*v[i];j--) { if(dp[j]<dp[j-num*v[i]]+num*p[i]) dp[j]=dp[j-num*v[i]]+num*p[i]; } sum+=num;num*=2; } num=n[i]-sum; for(j=N;j>=num*v[i];j--) { if(dp[j]<dp[j-num*v[i]]+num*p[i]) dp[j]=dp[j-num*v[i]]+num*p[i]; } } printf("%d\n",dp[N]); } return 0; }
二维背包
hdu3496
其中一维必须刚好装满
注意初始化
#include<stdio.h> #include<string.h> int dp[1001][101],v,p; int main() { int i,j,k,m,n,l,T; scanf("%d",&T); while(T--) { scanf("%d%d%d",&n,&m,&l); for(i=0;i<=l;i++) for(j=0;j<=m;j++) dp[i][j]=-999999999; for(i=0;i<=l;i++) dp[i][0]=0; for(i=1;i<=n;i++) { scanf("%d%d",&v,&p); for(k=m;k>=1;k--) for(j=l;j>=v;j--) if(dp[j][k]<dp[j-v][k-1]+p) dp[j][k]=dp[j-v][k-1]+p; } if(dp[l][m]>0) printf("%d\n",dp[l][m]); else printf("0\n"); } return 0; }