hdu 2844 Coins(多重背包+二进制优化)

来源:互联网 发布:迪迦奥特曼act2.0淘宝 编辑:程序博客网 时间:2024/05/24 01:41

题目分析:同http://poj.org/problem?id=1742,在hdu 能过,poj TLE....


#include<iostream>#include<cstdio>using namespace std;const int maxn=100010;int A[120],C[120],V[120],m;//A[]代表价值,C[]代表数量,V[]代表体积int dp[maxn];//dp[i][j]代表前i件物品放入容量为j的背包的,可得最大价值void ZeroOnePack(int cost,int weight){for(int j=m;j>=cost;j--)dp[j]=max(dp[j],dp[j-cost]+weight);}void  CompletePack(int cost,int weight ){for(int j=cost;j<=m;j++)dp[j]=max(dp[j],dp[j-cost]+weight);}void MultiplePack(int cost,int weight,int amount){if(cost*amount>=m){CompletePack(cost,weight);return ;}int k=1;while(k<amount){ZeroOnePack(k*cost,k*weight);amount-=k;k*=2;}ZeroOnePack(amount*cost,amount*weight);}int main(){int n;while(scanf("%d %d",&n,&m)!=EOF){      if(n==0&&m==0)  break;  for(int i=1;i<=n;i++)  {  scanf("%d",&A[i]);  V[i]=A[i];  }  for(int i=1;i<=n;i++)  scanf("%d",&C[i]);  dp[0]=0;  for(int i=1;i<=maxn;i++)  dp[i]=0;  for(int i=1;i<=n;i++)  {   MultiplePack(A[i],V[i],C[i]);  /*  if(C[i]*A[i]>=m)  for(int j=V[i];j<=m;j++)  dp[i]=max(dp[i],dp[i-V[i]]+A[i]);  else  {  int k=1,amount=C[i];  while(k<amount)  {  for(int j=m;j>=k*V[i];j--)  dp[i]=max(dp[i],dp[i-k*V[i]]+k*A[i]);  amount-=k;  k*=2;  }  for(int j=m;j>=amount*V[i];j--)  dp[i]=max(dp[i],dp[i-amount*V[i]]+amount*A[i]);  }*/  }  int ans=0;  for(int i=1;i<=m;i++)  if(dp[i]==i)  ans++;  printf("%d\n",ans);}system("pause");return 0;}