如图所示的数字三角形,从顶部出发,在每一结点可以选择向左走或得向右走,一直走到底层,要求找出一条路径,使路径上的值最大。
第一行是数塔层数N(1<=N<=100)。
第二行起,按数塔图形,有一个或多个的整数,表示该层节点的值,共有N行。
输出最大值。
5
13
11 8
12 7 26
6 14 15 8
12 7 13 24 11
86
1、递归+记忆化搜索(《算法竞赛入门经典》的思路)
速度:3ms
#include <stdio.h> #include <string.h> int d[400][400],map[400][400],n; int max(int a,int b) { if(a>b) return a; return b; } int dp(int i,int j) { if(d[i][j]>=0) return d[i][j]; if(i==n) return map[i][j]+0; else return d[i][j]=map[i][j]+max(dp(i+1,j),dp(i+1,j+1)); } int main() { int i,j; memset(d,-1,sizeof(d)); scanf("%d",&n); for(i=1;i<=n;i++) //第i层 for(j=1;j<=i;j++)//第i层左起第j个元素 { scanf("%d",&map[i][j]); } int max=0; //dp(1,1); printf("%d\n",dp(1,1)); return 0; }
2、棋盘型DP
速度:0ms
#include <stdio.h> #define MAXN 200 int f[MAXN][MAXN]; //f[i][j]=从顶端到第i层第j个数的最大和 int map[MAXN][MAXN]; int max(int a,int b) { if(a>b) return a; return b; } int main() { int n,i,j; scanf("%d",&n); for(i=1;i<=n;i++) for(j=1;j<=i;j++) scanf("%d",&map[i][j]); for(i=1;i<=n;i++) for(j=1;j<=i;j++) { if(j==1) f[i][j]=f[i-1][j]; else if(j==i) f[i][j]=f[i-1][j-1]; else f[i][j]=max(f[i-1][j],f[i-1][j-1]); f[i][j]+=map[i][j]; } int maxf=-1; for(i=1;i<=n;i++) maxf=max(maxf,f[n][i]); printf("%d\n",maxf); return 0; }