一、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());
}
}