这是一道最最基础的dp题目,还记得当时看刘汝佳写的《入门经典》时,就是拿的这个做例子,不过牛人当然是一笔带过这么简单的例子。
状态转移方程为:dp[i][j]+=max(dp[i+1][j],dp[i+1][j+1]),如果要记录路径也简单,另外再用一个数组专门存放原始数组就好
原三角形是
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
dp三角形是
30
23 21
20 13 10
7 12 10 10
4 5 2 6 5
如果要记录路径,就是从dp[1][1](即30)开始,2选1较大的,并在input数组中找到对应的数即可。如:
30-->23-->20-->12-->5 对应有:
7 -->3 -->8 -->7 -->5
思路很清晰
AC的代码:
#include<stdio.h> int dp[352][352]; inline int max(int a,int b){return a>b?a:b;} int main() { int n,i,j; scanf("%d",&n); //输入 for(i=1;i<=n;i++) for(j=1;j<=i;j++) scanf("%d",&dp[i][j]); //dp for(i=n-1;i>=1;i--) for(j=1;j<=i;j++) dp[i][j]=max(dp[i][j]+dp[i+1][j],dp[i][j]+dp[i+1][j+1]); printf("%d\n",dp[1][1]); return 0; }
这道题用不用两个数组都可以,不过记录路径就要用
用两个数组就是要把第n层的数据复制过去
#include <stdio.h> int input[360][360]; int dp[360][360]; inline int max(int a,int b){return a>b?a:b;} int main() { int n; scanf("%d",&n); //输入 int i,j; for(i=1;i<=n;i++) for(j=1;j<=i;j++) scanf("%d",&input[i][j]); for(i=1;i<=n;i++) dp[n][i]=input[n][i]; //dp for(i=n-1;i>=1;i--) for(j=1;j<=i;j++) dp[i][j]=input[i][j]+max(dp[i+1][j],dp[i+1][j+1]); printf("%d\n",dp[1][1]); return 0; }
1.poj 3176 的结题报告:POJ3176-Cow Bowling
2.