动态规划的总结
4个步骤设计一个动态规划的算法
- 刻画一个最优解的结构特征
- 递归地定义最优解的值
- 计算最优解的值,通常采用自底向上的方法
- 利用计算出的信息构造一个最优解
钢条切割
出售长度为i英寸的钢条的价格为$p_i(i = 1, 2, 3, …, 单位为美元)$,给定一段长度为n英寸的钢条和一个价格表,求切割方案,使得销售利益最大
长度i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
价格$p_i$ | 1 | 5 | 8 | 9 | 10 | 17 | 17 | 20 | 24 | 30 |
考虑一段长度为n的钢条,我们可以将钢条分成(1, n-1),(2, n-2)….(n-1, 1)这几种,然后在这几种中寻找最优的方案,递归求已分割的两段的最优方案
用数学表达式描述为
$$r_n = max(p_n,\ r_1+r_{n-1},\ r_2+r_{n-2},…,\ r_{n-1} +r_1)$$
矩阵链乘法
给定一个n个矩阵的序列$< A_1, A_2, A_3, …, A_n >$,矩阵$Ai$的规模为$ p{i-1} * p_i(1 \leq i \leq n)$,求完全括号化方案,使得计算乘积所需标量乘法次数最少
最大连续子序列的和
给定数组,求数组的最大连续子序列的和
递推关系式为:
$$max\_sum[i+1] = max(max\_sum[i] + a[i+1], a[i+1])$$
我们想要的是
$$max\_sum = max(max\_sum[1], max\_sum[2],…, max\_sum[n])$$
1 | /*穷举法 O(n^3) */ |
1 | int MaxSubSequence(const int A[], int N){ |
1 | /*此处是对动态规划的一个变种*/ |
1 | /*动态规划*/ |
最长递增子序列(LIS)
最长递增子序列(LIS)的问题是要找到一个给定序列的最长子序列的长度,使得子序列中的所有元素被排序的顺序增加。
例如,{10,22,9,33,21,50,41,60,80}LIS的长度是6和LIS为{10,22,33,50,60,80}。给定数列array[n];
- 动态规划
dp[i]表示的是以array[i]结尾的LIS,则
$$dp[i] =
\begin{cases}
max(dp[j] + 1)\ (j = 0,1, 2..,i-1) ,& \text{如果$a[j]$ > $a[i]$} \\
1, & \text{otherwise} \\
\end{cases}$$
1 |
|