题目的方法我不过多叙述,可以去 网上搜一下DP的讲义,我这里用了两种方法来做,都是用二元组去描述状态的。代码直接可以运行,是第二种方法,直接求顶层的元素到底层每个元素的最大和值,去掉第二种,就是第一种,我已经注释表明,是求从顶层到下面每层没个数字的最大和值。题目很好,典型的DP思想
//数塔// //题目链接:http://acm.hdu.edu.cn/webcontest/contest_showproblem.php?cid=4493&pid=1001&ojid=1 #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int dp[200][200]; int high; int temp[200][200]; int result[200]; /* NO.1 int f(int a,int b) //求第a行第b个元素到底部的最大和值// { if(a==high) { dp[a][b]=temp[a][b]; return dp[a][b]; } if(dp[a][b]!=-1) return dp[a][b]; dp[a][b]=temp[a][b]+max(f(a+1,b),f(a+1,b+1)); return dp[a][b]; } */ //NO .2// int f(int a,int b) //求解顶层到第a层第b个元素的最大和值// { if(a==1) return temp[1][1]; if(dp[a][b]!=-1) return dp[a][b]; //记忆化剪枝// dp[a][b]=temp[a][b]+max(f(a-1,b-1),f(a-1,b)); return dp[a][b]; } int cmp(int x,int y) { return x>y; } int main() { int i,j,k; int cas; while(scanf("%d",&cas)!=EOF) { while(cas--) { scanf("%d",&high); memset(dp,0xff,sizeof(dp)); dp[1][1]=1; for(i=1;i<=high;i++) for(j=1;j<=i;j++) scanf("%d",&temp[i][j]); /* NO.1 printf("%d\n",f(1,1)); */ //NO.2// for(i=1;i<=high;i++) result[i]=f(high,i); sort(result+1,result+high+1,cmp); printf("%d\n",result[1]); //NO.2// } } return 0; }