标签: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