标签:des style blog io os ar java for sp
4
题目大意:给你几种硬币的价值和数量,再给你一个最大钱数M,问你这些硬币能
组成价值1到M的值有多少种
思路:简单的多重背包,如果总容量比这个物品的容量要小,那么这个物品可以直
接取完,相当于完全背包。否则的话就转成01背包来求解。
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int v[110],c[110]; int dp[100010],V; //v数组存价值,c数组存数量,V是总容量 void ZeroOne(int cost,int weight)//01背包 { for(int i = V; i >= cost; i--) dp[i] = max(dp[i],dp[i-cost]+weight); } void Complete(int cost,int weight)//完全背包 { for(int i = cost; i <= V; i++) dp[i] = max(dp[i],dp[i-cost]+weight); } void Multiple(int cost,int weight,int cnt)//多重背包 { //如果总容量比这个物品的容量要小,那么这个物品可以直接取完,相当于完全背包 if(V <= cnt*cost) { Complete(cost,weight); return; } else//否则就将多重背包转化为01背包 { int k = 1; while(k <= cnt) { ZeroOne(k*cost,k*weight); cnt -= k; k <<= 1; } ZeroOne(cnt*cost,cnt*weight); } } int main() { int N; while(~scanf("%d%d",&N,&V)&&(N!=0||V!=0)) { for(int i = 0; i < N; i++) scanf("%d",&v[i]); for(int i = 0; i < N; i++) scanf("%d",&c[i]); for(int i = 0; i <= V; i++)//初始化:是否恰好装满背包 dp[i] = -0xffffff0; dp[0] = 0; for(int i = 0; i < N; i++) Multiple(v[i],v[i],c[i]); int ans = 0; for(int i = 1; i <= V; i++) if(dp[i] >= 0) ans++; printf("%d\n",ans); } return 0; }
标签:des style blog io os ar java for sp
原文地址:http://blog.csdn.net/lianai911/article/details/40588307