硬币问题

来源:互联网 发布:mmd虎视眈眈动作数据 编辑:程序博客网 时间:2024/06/06 19:08

动态规划问题满足如下3点
(1)最优化原理:如果问题的最优解所包含的子问题的解也是最优的
(2)无后效性:即某阶段状态一旦确定,就不受这个状态以后的决策的影响
(3)有重叠子问题:即子问题之间不是独立的,一个子问题在下一阶段决策中可能被多次使用到


有1元,2元,5元面值的硬币若干枚,如何用最少的硬币凑出11元面值


如果用最少的硬币凑出n元(n < 11), 为什么要这样分析:
(1)当我们遇到一个大问题时,总是习惯把问题规模变小,这样便于分析
(2)规模变小后的问题和原来的问题是相同性质的,本质上还是一个问题

dp[n]: 最少需要多少个硬币来凑足n元
那么dp[0] = 0
dp[1] = 1, 凑足一元最少需要一个一元的硬币
dp[2] = min(dp[2-1]+1, dp[2-2]+1)
dp[3] = min(dp[3-1]+1, dp[3-2]+1)
....

#include <iostream>

using namespace std;

const int MAX = 65536;
int dp[MAX] = { 0 };
int key[3] = {1, 2, 5};

void calc(int sum)
{
    int tmp;
    bool flag = false;
    for (int i = 1; i < sum; ++i)
    {
        flag = true;
        for (int j = 0; j < sizeof(key)/sizeof(int); ++j)
        {
            if (key[j] <= i)
            {
                 dp[i] = dp[i - key[j]] + 1;
                 if (flag)
                 {
                     tmp = dp[i];
                     flag = false;
                 }
                 dp[i] = dp[i] > tmp ? tmp : dp[i];
            }
        }
    }
}

int main()
{
    calc(65535);
    cout << "11 -> " << dp[11] << " , " << "55 -> " << dp[55] << endl;

    return 0;
}


11 -> 3 , 55 -> 11

原创粉丝点击