动态规划____类数字三角形

 

一个由n行数字组成的三角形,第i行有2i-1个正整数(小于等于1000),如下:

3

7 1 4

2 4 3 6 2

8 5 2 9 3 6 2

 

要求你用笔从第1行画到n(0 < n ≤ 100)行,从当前行往下画的时候只能在相邻的数字经过,也就是说,如果从一行的一个数往下画,只能选择其左下或者正下或者右下三个数中的一个(如果存在的话),把所有被画起来的数字相加,得到一个和,求能得到的最大的和的值是多少。

上例中能得到的最大的和为3 + 7 + 4 + 9 = 23.

Input

第一行,一个自然数T,表示总共给出的三角形数,对于每一个三角形,首先给出一个自然数n,表示将输入的三角形有n行。接下来有n行,i行有2i-1个数字

红字部分特别注意:虽然行数 ≤ 100 但是 列数为 "第i行有2i-1个数字" 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX 300 //开100不行了!
#define INF -1

int map[MAX][MAX];
int in[MAX][MAX];
int line;

int m(int a, int b, int c)
{
    return a>b?(a>c?a:c):(b>c?b:c);
}

int dp(int i, int j)
{
    if(map[i][j] != INF)
        return map[i][j];
    else
    {
        if(i == line)//边界需要特殊处理
              return map[i][j] = in[i][j];
        else
            return map[i][j] = m( dp(i+1,j), dp(i+1,j+1), dp(i+1, j+2) ) + in[i][j];
    }
}


int main()
{
    int N;

    //freopen("1.txt", "r", stdin);
    scanf("%d", &N);    
    while(N--)
    {        
        int row;
        int i, j;

        memset(map, INF, sizeof(map));
        scanf("%d", &line);
        for(i = 1; i <= line; i++)//0行 0列不存东西
        {
            row = i * 2 - 1;
            for(j = 1; j <= row; j++)
            {
                scanf("%d", &in[i][j]);    
            }    
        }
        
        dp(1,1);        
        printf("%d\n", map[1][1]);
    }

}

 

 

 

posted on 2013-06-28 21:10  wwjyt  阅读(262)  评论(0编辑  收藏  举报