最小数目的硬币组合问题(dp)
问题:给出硬币种类,及要组合的sum,求用最少的硬币数目到达sum。
例如:硬币种类1,5,8 sum为20,则最少的硬币数目为5555。
分析此题,立刻想到的思路是贪心,从大的往小的搜索,最后到达sum后返回,仔细想想,这个思路是不对的。
看上面的例子,正确答案为5555,可是我们用刚才的思路则得出的结论为881111,显然是不对的。
想想错误原因,很简单,我们第一步选择8,剩余的12个问题的最优解不一定就是原问题的最优解,所以此题采用动态规划
即算出达到当前状态的前一个状态的所有值,我们取最小的。
令dp[i]表示sum为i时的最小硬币数目,则dp[i] = min{dp[i-aj] + 1, 0<=j<=a_len && a[j]<=i}.
有了dp方程,很快便可写出程序了:
memset(dp, INF, sizeof(dp));
dp[0] = 0;
for(i = 1; i <= sum; ++i)
{
for(j = 0; j <= a_len; ++j)
{
if(a[j] <= i && dp[i - a[j]] + 1 < dp[i])
dp[i] = dp[i - a[j]] + 1;
}
}
posted on 2012-04-01 17:00 buptLizer 阅读(2286) 评论(0) 编辑 收藏 举报