HDU 2408-数塔(动态规划入门)

题目描述

2.题目描述
       7 
      3 8 
     8 1 0 
    2 7 4 4 
   4 5 2 6 5 
上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,和最大的路径称为最佳路径。求出最佳路径上的数字之和。路径上的每一步只能从一个数走到下一层上和它最近的左边的数或者右边的数。以上样例答案为 30。
3.分析
这道题目可以用递归的方法解决。基本思路是:以 D( r, j)表示第 r 行第 j 个数字(r,j 都从 1 开始算),以 MaxSum(r, j) 代表从第 r 行的第 j 个数字到底边的最佳路径的数字之和,则本题是要求 MaxSum(1, 1) 。从某个D(r, j)出发,显然下一步只能走 D(r+1, j)或者 D(r+1, j+1)。如果走 D(r+1, j),那么得到的MaxSum(r, j)就是 MaxSum(r+1, j) + D(r, j);如果走 D(r+1, j+1),那么得到的 MaxSum(r, j)就是 MaxSum(r+1, j+1) + D(r, j)。所以,选择往哪里走,就看 MaxSum(r+1, j)和 MaxSum(r+1, j+1)哪个更大了。这种将一个问题分解为子问题递归求解,并且将中间结果保存以避免重复计算的办法,就叫做“动态规划”。动态规划通常用来求最优解,能用动态规划解决的求最优解问题,必须满足,最优解的每个局部解也都是最优的。以上题为例,最佳路径上面的每个数字到底部的那一段路径,都是从该数字出发到达到底部的最佳路径。实际上,递归的思想在编程时未必要实现为递归函数。在上面的例子里,有递推公式:因此,不需要写递归函数,从 aMaxSum[N-1]这一行元素开始向上逐行递推,就能求得最终 aMaxSum[1][1]的值了。


#include <stdio.h> 
#define MAX 100+10 
int D[MAX][MAX]; 
int N; 
int aMaxSum[MAX][MAX]; 
int main()
{
  int i, j; 
  scanf("%d", & N);
  for(i = 1; i <= N; i ++) 
    for(j = 1; j <= i; j ++) 
      scanf("%d", &D[i][j]); 
  for(j = 1; j <= N; j ++) 
    aMaxSum[N][j] = D[N][j]; 
  for(i = N ; i > 1 ; i --) 
    for(j = 1; j < i ; j ++)
    { 
      if(aMaxSum[i][j] > aMaxSum[i][j+1]) 
        aMaxSum[i-1][j] = aMaxSum[i][j] + D[i-1][j]; 
      else 
        aMaxSum[i-1][j] = aMaxSum[i][j+1] + D[i-1][j]; 
    } 
  printf("%d\n", aMaxSum[1][1]); 
}

 

Guess you like

Origin blog.csdn.net/qq_24016309/article/details/88700059