最小数目的硬币组合问题(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编辑  收藏  举报

导航