http://acm.hdu.edu.cn/showproblem.php?pid=2844
求的是能买多少种价钱的物品,多重背包
教主很经典的男人八题之一。。。不过据说原题要用单调队列优化,这个二进制优化就过了。。。
View Code
#include <iostream> using namespace std ; int V ; int dp[100001] ; void ZeroOnePack(int c,int w) { for(int i=V;i>=c;i--) dp[i]=max(dp[i],dp[i-c]+w) ; return ; } void CompletePack(int c,int w) { for(int i=c;i<=V;i++) dp[i]=max(dp[i],dp[i-c]+w) ; return ; } void MultiplePack(int c,int w,int a) { if(c*a>=V) { CompletePack(c,w) ; return ; } int k=1 ; while(k<a) { ZeroOnePack(k*c,k*w) ; a-=k ; k<<=1 ; } ZeroOnePack(a*c,a*w) ; } int num[100001],w[100001] ; int main() { int n,m ; while(scanf("%d%d",&n,&m),n+m) { for(int i=1;i<=n;i++) scanf("%d",&w[i]) ; for(int i=1;i<=n;i++) scanf("%d",&num[i]) ; V=m ; memset(dp,0,sizeof(dp)) ; for(int i=1;i<=n;i++) MultiplePack(w[i],w[i],num[i]) ; int ans=0 ; for(int i=1;i<=m;i++) if(dp[i]>=i) ans++ ; printf("%d\n",ans) ; } return 0 ; }