#include<stdio.h>
#define N 105
int map[N][N],height,result_map[N][N];
void initialize() //initialize maps
{
for(int i = 0;i<N;i++)
for(int j = 0;j<N;j++)
{
map[i][j] = -1;
result_map[i][j] = -1;
}
}
void input() //input the data
{
int sum;
scanf("%d",&height);
sum = height*(height+1)/2;
for(int n = 1,i = 1,j = 1;n<=sum;n++,j++)
{
if(n>=((i+1)*i/2 +1))
{
i += 1;
j = 1;
}
scanf("%d",&map[i][j]);
}
for(int i = 0;i<N;i++)
{
result_map[height][i] = map[height][i];
}
}
int result(int i ,int j)
{
if(result_map[i][j] == -1)
{
result_map[i][j] = (( result(i+1,j)>result(i+1,j+1) )?result(i+1,j):result(i+1,j+1)) + map[i][j];
}
return result_map[i][j];
}
int output()
{
printf("%d\n",result(1,1));
}
int main()
{
int count;
scanf("%d",&count);
while(count--)
{
initialize();
input();
output();
}
return 0;
}
同样,这道也是最简单经典的动态规划题目。
些动态规划的题目最重要的是找到决策方法,然后找到状态转移方程。当方程列出来的时候,这道题便已经解决了。
这里的result_map[i][j] 记录的是走到第i层第j个元素经过的结点的数字之和的最大值。
状态转移方程:dp[i][j] = max { dp[i+1][j] , dp[i+1][j+1] } + map[i][j]。
自然语言描述就是第i层第j个元素经过的结点的数字之和的最大值仅仅取决于第i+1层第j个元素和第i+1层的第j+1个元素。这样,我们就把大的问题转换成了小的问题,找到了限制(i,j)点值的因素后,我们就很简单的可以使用动态规划写出来了。解决上层问题,需要先解决下层问题。这样,如果我们使用递推,我们应当从底层向高层运算。一步一步找到最后的结果。
然后这道题就结了~