一个由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 ", map[1][1]); } }