题目:http://poj.org/problem?id=1163
动态规划的基础问题。
对于每一个点来说,所求为:该点数值+Max{左上角点所求值,右上角点所求值};
这也就是说,每一个问题都可以拆分成规模更小但是求解思路完全相同的子问题,当问题被一层一层简化,我们发现只要能够得到最简单问题的解,所有在其基础上建立起来的问题就都能够像骨牌一样被求出。
不过在问题的具体求解上,我们采用自底向上的求解模式。“底”是最底层的问题,从他开始向上逐个求解。每个点求得结果我们都把它存放在一个功能类似于“记事本”的数组当中,以便后续再次调用时直接搜索从而避免重复的运算。
代码(注意代码中加1或减一的细节)
#include<iostream>
using namespace std;
int summest(int list[101][101],int n);
int main()
{
int n;
cin>>n;
//对于位置的确定我们想到的方法是二维数组;
int list[101][101];
for(int i=0;i<n;i++)
for(int j=0;j<=i;j++)
cin>>list[i][j];
cout<<summest(list,n)<<endl;
return 0;
}
int summest(int list[101][101],int n)
{
//“记事本”数组;
int mem[101][101];
for(int i=0;i<=n;i++)
for(int j=0;j<=i;j++)
mem[i][j]=0;
mem[0][0]=list[0][0];
for(int i=1;i<n;i++)
for(int j=0;j<=i;j++)
{
int p=-1;
//确保所求点右上方有点;
if(j!=i)
if(list[i][j]+mem[i-1][j]>p)
{
p=mem[i-1][j]+list[i][j];
mem[i][j]=p;
}
//确保所求点左上方有点;
if(j!=0)
if(list[i][j]+mem[i-1][j-1]>p)
{
p=mem[i-1][j-1]+list[i][j];
mem[i][j]=p;
}
}
//对最后一行数字进行筛选;
int max=mem[n-1][0];
for(int i=0;i<n;i++)
if(mem[n-1][i]>max)
max=mem[n-1][i];
return max;
}