一、Description
7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 (Figure 1)
Input
Your program is to read from standard input. The first line contains one integer N: the number of rows in the triangle. The following N lines describe the data of the triangle. The number of rows in the triangle is > 1 but <= 100.
The numbers in the triangle, all integers, are between 0 and 99.
Output
Your program is to write to standard output. The highest sum is written as an integer.
二、问题分析
DP问题,和之前做的1088滑雪属于同一类问题。解这个问题与解其它的DP问题几乎没有什么两样。第一步找到问题的“状态”,第二步找到“状态转移方程”,然后基本上问题就解决了。首先,我们要找到这个问题中的“状态”是什么?我们必须注意到的一点是,到达终点坐标的方式最多有两种:根据数组存放的特点有向下和斜右下两个方向。所以,终点之前的点,可以由终点向上和斜左上两个方向。从两个方向中选出路径值最大的。而所选出的这个坐标又可以当成是一个子问题递归求解。由于使用了记忆化存储,所以可以先直接查表,如果表中存在子问题的解则直接返回,否则就按上面的分析过程找到最大路径并存储。经过上面的分析,很容易可以得出问题的状态和状态转移方程。
二、问题分析
DP问题,和之前做的1088滑雪属于同一类问题。解这个问题与解其它的DP问题几乎没有什么两样。第一步找到问题的“状态”,第二步找到“状态转移方程”,然后基本上问题就解决了。首先,我们要找到这个问题中的“状态”是什么?我们必须注意到的一点是,到达终点坐标的方式最多有两种:根据数组存放的特点有向下和斜右下两个方向。所以,终点之前的点,可以由终点向上和斜左上两个方向。从两个方向中选出路径值最大的。而所选出的这个坐标又可以当成是一个子问题递归求解。由于使用了记忆化存储,所以可以先直接查表,如果表中存在子问题的解则直接返回,否则就按上面的分析过程找到最大路径并存储。经过上面的分析,很容易可以得出问题的状态和状态转移方程。
S[i][j]=arr[x][y] + max(S[i-1][j], if i>1 ; S[i-1][j-1], if j>1,x>1 ),x和y为当前结点的值。
小弟Poj第二十题,水分不少,一水到底。
三、java代码
import java.util.Scanner; public class Main { private int[][] a; private int[][] m; private int n; private void init(){ Scanner cin=new Scanner(System.in); n=cin.nextInt(); a=new int[n+1][n+1]; m=new int[n+1][n+1]; for(int i=1;i<=n;i++){ for(int j=1;j<=i;j++){ a[i][j]=cin.nextInt(); m[i][j]=-1; } } } public int searchMaxRoute(int x,int y){ if( m[x][y]!=-1) return m[x][y]; else{ int max=0; if(x>1){ max=Math.max(max,searchMaxRoute(x-1,y)); } if(x>1 && y>1){ max=Math.max(max,searchMaxRoute(x-1,y-1)); } m[x][y]=max+a[x][y]; return m[x][y]; } } public int getMaxHeight(){ int temp; int Max=-1; for(int i=n;i>=1;i--){ for(int j=1;j<=n;j++){ temp=searchMaxRoute(i,j); if(Max< temp) Max=temp; } } return Max; } public static void main(String[] args) { Main m=new Main(); m.init(); System.out.println(m.getMaxHeight()); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。