经典数塔问题
有一金字塔形数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?
输入数据首先包括一个整数C,表示测试实例的个数,每个测试实例的第一行是一个整数N(1 <= N <= 100),表示数塔的高度,接下来用N行数字表示数塔,其中第i行有个i个整数,且所有的整数均在区间[0,99]内。
输入样例
1
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出样例
30
动态规划代码
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int f[N][N], dp[N][N];
int main(){
int C, n;
cin >> C;
while(C--) {
scanf("%d", &n);
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= i; j ++){
scanf("%d", &f[i][j]);
}
}
for(int j = 1; j <= n; j ++)
dp[n][j] = f[n][j];
for(int i = n - 1; i >= 1; i --){
for(int j = 1; j <= i; j ++){
dp[i][j] = max(dp[i + 1][j], dp[i + 1][j + 1]) + f[i][j];
}
}
printf("%d\n", dp[1][1]);
}
return 0;
}
分治与动态规划
分治与动态规划都是将问题分解成子问题,然后合并子问题的解得出原问题的解。不同的是,分治分解的子问题是不重叠的(如快速排序将问题分为处理左序列与右序列),而动态规划问题相反。同时,动态规划一定解决的是最优化问题,而分治不一定。
贪心与动态规划
它们都是将问题变成处理子问题,都要求原问题拥有最优子结构。二者的区别在于,贪心类似于“自顶向下”,但是是通过一种最优策略直接选择一个子问题求解,其它子问题则直接舍弃。这就是说,它总是在上一步选择的基础上继续选择,整个过程是单链的。显然,这种“最优选择策略”的正确性需要进一步归纳证明。比如数塔问题,贪心法会从第一层开始,选择下面两数更大的那个一直走下去,显然这并不一定能得到最优解。而动态规划不管是自顶向下还是自底向上,本质上都是从边界开始得到目标问题的最优解。也就是说,它会考虑完所有子问题,并选择继承能得到最优结果的那个,对于暂时没被继承的子问题也不会直接舍弃——由于重叠子问题的存在,后期可能会再次考虑它们,因此它们仍然有机会成为全局最优的一部分。
贪心是一种壮士断腕的决策——只要进行的选择就一直走下去不后悔;动态规划则是动态地考虑问题,看谁能笑到最后——局部的领先不代表全局的领先。
《春子超常现象研究所》喜剧片高清在线免费观看:https://www.jgz518.com/xingkong/75134.html