题意:已知金额cash,给定几种不同面值的货币的数量及面值,求利用给定的货币可以凑成
小于等于cash的金额的最大值
分析:因为每种货币的面值及数量已知,可以将其转化为多重背包,背包的容量即为cash,
每个物品的价值及费用都为每种货币的面值。
多重背包可以转化为01背包,不过这样会超时,为了避免这样,可以转化为完全背包和二进制思想的01背包
#include<stdio.h> #include<string.h> int f[100010],v; int max(int a,int b) { return a>b?a:b; } void zeroone(int cost,int weight) //01背包 { int i; for(i=v;i>=cost;i--) f[i]=max(f[i],f[i-cost]+weight); } void complete(int cost,int weight) //完全背包 { int i; for(i=cost;i<=v;i++) f[i]=max(f[i],f[i-cost]+weight); } void multiple(int num,int cost,int weight) //多重背包 { int k; if(num*weight>=v){ complete(cost,weight); return ; } for(k=1;k<num;k*=2){ zeroone(k*cost,k*weight); num-=k; } zeroone(num*cost,num*weight); } int main() { int i,n,num[1010],w[1010]; while(scanf("%d",&v)!=EOF){ scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d%d",&num[i],&w[i]); memset(f,0,sizeof(f)); for(i=1;i<=n;i++) multiple(num[i],w[i],w[i]); printf("%d\n",f[v]); } return 0; }
poj 1276 Cash Machine (多重背包)
时间: 2024-10-11 18:07:51