零钱兑换问题:
已知各种金币面值costs[i](每种面值可无限使用),求兑换出指定金额target的最小钱币数。
此题有dfs等的解法,这里只介绍完全背包的解法:
先上状态转移方程:
f[i][v]表示处理前i种钱币时,刚好兑换面值为v时的钱币数,则
f[i][v]=min{f[i-1][v],f[i][v-costs[i]]+1}
上述方程简化为一维数组实现(可参考我的背包九讲笔记)如下:
int getMinValue(vector<int>&costs, int target)
{
vector<int> results(target+1,INT_MAX/2);
for (int i=0;i<=target;++i)
{
if (i%costs[0]==0)//只有金额为costs[0]的整数倍,才可有兑换结果
{
results[i] = i / costs[0];
}
}
for (int i=1;i<costs.size();++i)
{
for (int j=0;j<=target;++j)
{
if (j>=costs[i])
{
results[j] = min(results[j], results[j - costs[i]] + 1);
}
}
}
return results[target];
}
时间复杂度O(N*target),空间复杂度O(target)