地址:http://acm.nyist.net/JudgeOnline/problem.php?pid=18
The Triangle
时间限制:1000 ms | 内存限制:65535 KB
难度:4
-
描述
-
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
(Figure 1)
Figure 1 shows a number triangle. Write a program that calculates the highest sum of numbers passed on a route that starts at the top and ends somewhere on the base. Each step can go either diagonally down to the left or diagonally down to the right.-
输入
- 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. 输出
- Your program is to write to standard output. The highest sum is written as an integer. 样例输入
-
5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5
样例输出 -
30
思路:动态规划典型的数塔问题,一开始就有着感觉,有点像tsp问题,每个值都有两条路,记录全部得到最大的值。但是,这样想就把问题想复杂了。数塔问题有更简单的,就是一种逆向的思维,从底部往上面推,得到第一个的时候,就是最大的结果了,如果保存路径,一样自底向上,然后自顶向下,因为当前是保存着下一个的最优的路径的决策的。用手+笔进行模拟一下,思路就会很清晰了。
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner cin=new Scanner(System.in);
int length=cin.nextInt();
int[][] arr=new int [length][length];
for(int i=0;i<length;i++){
for(int j=0;j<=i;j++){
arr[i][j]=cin.nextInt();
}
}
dataTower(arr, length);
}
//113 1091
public static void dataTower(int [][] arr,int length){
for(int i=length-2;i>=0;i--){ //自底向上,一种逆向的思维,将最大的答案冒泡出来
for(int j=0;j<=i;j++){
arr[i][j]=arr[i][j]+max(arr[i+1][j],arr[i+1][j+1]);
}
}
System.out.println(arr[0][0]);
}
public static int max(int a,int b){
return a>b?a:b;
}
//记录完路径
public static void dataTowerPath(int[][] arr,int length){
int[][] maxAdd=new int[length][length];
int[][] path=new int[length][length];
int i,j;
for(j=0;j<length;j++) //初始化底层决策结果
maxAdd[length-1][j]=arr[length-1][j];
for(i=length-2;i>=0;i--){
for(j=0;j<=i;j++){
if(maxAdd[i+1][j]>maxAdd[i+1][j+1]){
maxAdd[i][j]=arr[i][j]+maxAdd[i+1][j];
path[i][j]=j; //决定本次的决策,从底向上,最终汇成一点,在从顶向下,当前会存下一个最大的路径决策
}
else{
maxAdd[i][j]=arr[i][j]+maxAdd[i+1][j+1];
path[i][j]=j+1; //似乎保存完了所有的路径,但是从顶开始,是保留吓一跳的路径决策
}
}
}
System.out.println(maxAdd[0][0]);
j=path[0][0]; //顶层决策是选择下一层列下标为path[0][0]的元素
for(i=1;i<length;i++){
System.out.print("-->"+arr[i][j]);
j=path[i][j]; //顶层决策是选择下一层列下标为path[i][j]的元素
}
}
}