简单动态规划两例。
1 最优子结构
当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质。最优子结构性质提供了该问题的可用动态规划算法求解的重要线索。
动态规划,利用问题的最优子结构性质,以自底向上的方式递归的从子问题的最优解逐步构造出整个问题的最优解。
2 重叠子问题
动态规划,避开了递归时,重复的计算相同子问题的过程,对每个子问题只解一次,而后将其保存在一个表格中,当再次需要的时候,只是简单的用常数时间查看一下结果。
3 备忘录方法
递归方式自顶向下
首先,查看其相应的记录项,若存在,直接返回。若不存在,则保存,以备以后继续查看
一:最长递增序列
#include <iostream>
using namespace std;
int lis(int A[], int n){
int *d = new int[n];
int len = 1;
for (int i = 0; i<n; ++i)
{
d[i] = 1;
for (int j = 0; j<i; ++j)
{
if (A[j] <= A[i] && d[j] + 1>d[i])
d[i] = d[j] + 1;
}
if (d[i]>len)
len = d[i];
}
delete[] d;
return len;
}
int main(){
int A[] = {
5, 3, 4, 8, 6, 7
};
cout << lis(A, 6) << endl;
return 0;
}
二:找零问题
#include<iostream>
using namespace std;
int main()
{
int n, m;
int a[500] = { 0 };
int b[10000] = { 0 };
cout << "请输入硬币面值的个数:";
cin >> n;
cout << "请输入各个硬币的面值:";
for (int i = 1; i <= n; i++)
cin >> a[i];
cout << "请输入要找的钱:";
cin >> m;
void coin(int n, int m, int a[], int b[]);
coin(n, m, a, b);
cout << "最优解为:" << b[m] << endl;
return 0;
}
void coin(int n, int m, int a[], int b[])
{
b[0] = 0;
for (int i = 1; i <= m; i++)
{
int min = m;
for (int j = 1; j <= n; j++)
{
if (i >= a[j] && b[i - a[j]] < min)
min = b[i - a[j]];
}
b[i] = min + 1;
}
}