The Triangle(POJ - 1163)

 

The Triangle

 POJ - 1163 

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.

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.

Sample Input

5
7
3 8
8 1 0 
2 7 4 4
4 5 2 6 5

Sample Output

30

思路1:

  • dfs+记忆型递归

AcCode:

import static java.lang.Math.max;

import java.util.Scanner;

public class Main{
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int N = in.nextInt();
		int[][] nums = new int[N][N];
		for (int i = 0; i < nums.length; i++) {
			for (int j = 0; j <= i; j++) {
				nums[i][j] = in.nextInt();
			}
		}
		cache = new int[N][N];
		for (int i = 0; i < nums.length; i++) {
			for (int j = 0; j <=i; j++) {
				cache[i][j] = -1;
			}
		}
		int res = dfs(nums,0,0);
		System.out.println(res);
	}
	static int[][] cache = null;
	private static int dfs(int[][] nums, int i, int j) {
		if(cache[i][j]>=0) {
			return cache[i][j];
		}
		int leftDown = 0;
		int rightDown = 0;
		//往左下走
		if(i+1

 思路2:

  • 使用二维数组自底向上dp
  • dp[i][j] = nums[i][j] + max(dp[i+1][j],dp[i+1][j+1])

AcCode:

import static java.lang.Math.max;

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int N = in.nextInt();
		int[][] nums = new int[N][N];
		for (int i = 0; i < nums.length; i++) {
			for (int j = 0; j <=i; j++) {
				nums[i][j] = in.nextInt();
			}
		}
		int res = dp(nums);
		System.out.println(res);
	}

	private static int dp(int[][] nums) {
		int[][] dp = new int[nums.length][nums.length];
		//初始化
		for (int j = 0; j < dp[nums.length-1].length; j++) {
			dp[nums.length-1][j] = nums[nums.length-1][j];
		}
		for (int i = nums.length-2; i >=0 ; i--) {
			for (int j = 0; j <=i; j++) {
				dp[i][j] = nums[i][j]+max(dp[i+1][j],dp[i+1][j+1]);
			}
		}
		return dp[0][0];
	}
}

思路3:

  •  跟上面dp的思路一样,但是存值的时候使用一维的滚动数组更节约内存
  • dp[j] = nums[i][j]+max(dp[j],dp[j+1])
import static java.lang.Math.max;

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int N = in.nextInt();
		int[][] nums = new int[N][N];
		for (int i = 0; i < nums.length; i++) {
			for (int j = 0; j <=i; j++) {
				nums[i][j] = in.nextInt();
			}
		}
		//二维dp
//		int res = dp(nums);
//		System.out.println(res);
		//滚动数组-一维dp
		int res2 = dp2(nums);
		System.out.println(res2);
	}
	
	

	private static int dp2(int[][] nums) {
		int[] dp = new int[nums[nums.length-1].length];
		for (int j = 0; j < dp.length; j++) {
			dp[j] = nums[nums.length-1][j];
		}
		
		for (int i = nums.length-2; i >=0; i--) {
			for (int j = 0; j <=i; j++) {
				dp[j] = nums[i][j]+max(dp[j], dp[j+1]);
			}
		}

		return dp[0];
	}



	private static int dp(int[][] nums) {
		int[][] dp = new int[nums.length][nums.length];
		//初始化
		for (int j = 0; j < dp[nums.length-1].length; j++) {
			dp[nums.length-1][j] = nums[nums.length-1][j];
		}
		for (int i = nums.length-2; i >=0 ; i--) {
			for (int j = 0; j <=i; j++) {
				dp[i][j] = nums[i][j]+max(dp[i+1][j],dp[i+1][j+1]);
			}
		}
		return dp[0][0];
	}
}

 

 

 

 

你可能感兴趣的:(POJ)