动态规划(dynamic programming)网上大家都简称为DP。DP的核心思想就是找出各阶段各子问题之间的关系,然后利用各阶段的关系逐个求解。其中比较经典的题目就是数塔和最长有序子序列的求解。
数塔
题目 :有形如下面所示的数塔,从顶部出发,在每一节点可以选择向左走或是向右走,一直走到底层,需求找出一条路径,使路径上的值最大。
解题思路路:从顶点出发时到底向左走还是向右走应取决于是从左走能取到最大值还是从右走能取到最大值,只要左右两道路径上的最大值求出来了才能作出决策。同样,下一层的走向又要取决于再下一层上的最大值是否已经求出才能决策。这样一层一层推下去,直到倒数第二层时就非常明了。如数字2,只要选择它下面较大值的结点19前进就可以了。所以实际求解时,可从底层开始,层层递进,最后得到最大值。
结论:自顶向下的分析,自底向上的计算。
如图创建这样一个数组记录该点目前为止距离底层最长的距离。然后其上一层可以经过简单比较得出所求。得出答案为:59!
59
50 49
38 34 29
21 28 19 21
19 7 10 4 16
代码如下:
TIME:484MS //由于是O(n^2)的复杂度所以MS略高。
MEM;352K
#include <iostream>
using namespace std;
int main()
{
int c;
cin>>c;
short sum[101][100];
while(c--)
{
int N;
cin>>N;
for(int i=1; i<=N; i++)
{
for(int j=1; j<=i; j++)
cin>>sum[i][j];
}
short max;
for(int i=N-1;i>=1;i--)
{
max = 0;
for(int j=1; j<=i; j++)
{
max = sum[i+1][j]>sum[i+1][j+1]?sum[i+1][j]:sum[i+1][j+1];
sum[i][j] += max;
}
}
cout<<sum[1][1]<<endl;
}
return 0;
}