给定一张整钱C,换成不同的硬币,要求换成的硬币数量最少。
通过前面文章:背包总结中的完全背包,我们把找零问题应用到完全背包上面。
先贴上代码和测试结果:
/*
* 硬币找零问题
* C,整钱数目,与背包问题中背包的容量所对应
* w为硬币面值,与背包问题中物品的重量所对应
* v为硬币价值,与背包问题中物品的价值所对应
*/
void newknapsack11(int n, int C, int w[], int v[])
{
int V[C+1];
V[0] = 0;
for(int i=1; i<C+1; ++i)
V[i] = i;
for(int i = 1; i <= n; i++)
{
//注意,这里是逆序,为了获取i-1时的V值
for(int j = 0; j <= C; ++j)
{
//如果放得下
if(j >= w[i])
{
if(V[j-w[i]]+v[i] <= V[j])
{
V[j] = V[j-w[i]]+v[i];
}
}
}
for(int j=0; j<=C; ++j)
{
cout<<V[j]<<" ";
}
cout<<endl;
}
printf("the biggest value is %d\n", V[C]);
}
测试代码:
int weight[4] = {0, 1, 2, 5};
int value[4] = {0, 1, 1, 1};
newknapsack11(3, 10, weight, value);
结果:
0 1 2 3 4 5 6 7 8 9 10
0 1 1 2 2 3 3 4 4 5 5
0 1 1 2 2 1 2 2 3 3 2
the biggest value is 2。
通过注释部分大体了解了参数的作用。这个代码和前面文章的完全背包代码很像。区别在于:
1>. 完全背包是往背包里添东西,找零问题是从整钱里面往出扣钱。因此,找零问题中V[C+1]初始化时,V[i]初始化为钱数i可以兑换成的最多的硬币数量。而完全背包中V[i]初始化为i容量的背包初始装的东西。
2>. 找零问题要找一个最小值,所以核心代码从f[v] = max{f[v], f[v-c[i]]+w[i]}变成了f[v] = min{f[v], f[v-c[i]]+w[i]};