动态规划问题满足如下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