8.12 动态规划例题---数字三角形。 对于动态规划,根据依赖关系,先求被依赖的部分

题目:

解法一:递归


import java.util.Arrays;
import java.util.Scanner;

public class Main {
 /* 
  * 思路:
  * 通过深度优先遍历,从上往下进行查找
  * 每次将当前点作为起点,寻找最长路径。该点+该点往后的最长路径
测试数据:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
  * */
	static int n; //行数
	static int[][] g; //存储三角形
	static int ans; //存放最大值
	public static void main(String[] args) {
		//(1)输入相关数据
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		g = new int[n][];//创建行
		for(int i=0;i<n;i++) {
			g[i] = new int[i+1];//针对每一行初始化
			for(int j=0;j<=i;j++) {
				g[i][j]=sc.nextInt();
			}
		}
		//(2)进行深度优先遍历,获取最大值
		ans = dfs(0,0);
		System.out.println(ans);
	}
	//递归
	private static int dfs(int x, int y) {
		if(x==n-1) {//遍历到最后一行,以该点为起点,最长路径只能是其本身
			return g[x][y];
		}
		return g[x][y]+Math.max(dfs(x+1,y),dfs(x+1,y+1));//当前行x的元素g[x][y] + 以该点为起点的最长路径
	}	
}

解法二:记忆型递归(提高效率,避免重复计算)


import java.util.Arrays;
import java.util.Scanner;

public class Main {
 /* 
  * 思路:
  * 通过深度优先遍历,从上往下进行查找
  * 每次将当前点作为起点,寻找最长路径。该点+该点往后的最长路径
测试数据:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
  * */
	static int n; //行数
	static int[][] g; //存储三角形
	static int ans; //存放最大值
	static int[][] rem;//rem[x][y],记忆以点(x,y)作为起点的最长路径
	public static void main(String[] args) {
		//(1)输入相关数据
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		g = new int[n][];//创建行
		for(int i=0;i<n;i++) {
			g[i] = new int[i+1];//针对每一行初始化
			for(int j=0;j<=i;j++) {
				g[i][j]=sc.nextInt();
			}
		}
		rem = new int[n][n];
		//(2)进行深度优先遍历,获取最大值
		ans = dfs(0,0);
		System.out.println(ans);
	}
	//递归
	private static int dfs(int x, int y) {
		if(x==n-1) {//遍历到最后一行,以该点为起点,最长路径只能是其本身
			return g[x][y];
		}
		//(1)计算前先查找是否已存在
		if(rem[x][y]>0) return rem[x][y];
		
		int p = g[x][y]+Math.max(dfs(x+1,y),dfs(x+1,y+1));//当前行x的元素g[x][y] + 以该点为起点的最长路径
		//(2)计算后,将结果存到rem
		rem[x][y]=p;
		return p;
	}	
}

解法三:动态规划(从底向上查找)使用二维dp数组


import java.util.Arrays;
import java.util.Scanner;

public class Main {
 /* 
  * 思路:
  *通过动态规划,从底向上进行查找(先确定被依赖点的最大路径)。可知从上层出发的点的最大路径 都依赖于 下一层的大小,故先确定最底层
测试数据:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
  * */
	static int n; //行数
	static int[][] g; //存储三角形
	static int[][] dp;//dp[i][j]从点(i,j)出发的最长路径
	public static void main(String[] args) {
		//(1)输入相关数据
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		g = new int[n][];//创建行
		for(int i=0;i<n;i++) {
			g[i] = new int[i+1];//针对每一行初始化
			for(int j=0;j<=i;j++) {
				g[i][j]=sc.nextInt();
			}
		}
		//(2)初始化dp的最后一行,以该行上的点作为起点的最大路径都是其本身
		dp = new int[n][n];
		for(int i=0;i<n;i++) {
			dp[n-1][i] = g[n-1][i];
		}
		for(int i=n-2;i>=0;i--) {//依次确定每一行
			for(int j=0;j<=i;j++) {
				dp[i][j]=g[i][j]+Math.max(dp[i+1][j], dp[i+1][j+1]);//以(i,j)作为起点的最大路径
			}
		}
		//(2)进行深度优先遍历,获取最大值
		System.out.println(dp[0][0]);
	}
	
}

解法四:使用一维dp数组。初始化为最后一行的值,每次更新该数组的值,最后dp[0]为最大路径。(节约空间)

 dp中存放当前行中的点 为起点的最大路径


import java.util.Arrays;
import java.util.Scanner;

public class Main {
 /* 
  * 思路:
  *通过动态规划,从底向上进行查找(先确定被依赖点的最大路径)。可知从上层出发的点的最大路径 都依赖于 下一层的大小,故先确定最底层
测试数据:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
  * */
	static int n; //行数
	static int[][] g; //存储三角形
	static int[] dp;//dp[i][j]从点(i,j)出发的最长路径
	public static void main(String[] args) {
		//(1)输入相关数据
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		g = new int[n][];//创建行
		for(int i=0;i<n;i++) {
			g[i] = new int[i+1];//针对每一行初始化
			for(int j=0;j<=i;j++) {
				g[i][j]=sc.nextInt();
			}
		}
		//(2)初始化dp的最后一行,以该行上的点作为起点的最大路径都是其本身
		dp = new int[n];
		for(int i=0;i<n;i++) {
			dp[i] = g[n-1][i];
		}
		for(int i=n-2;i>=0;i--) {//依次确定每一行
			for(int j=0;j<=i;j++) {	
				dp[j]=g[i][j]+Math.max(dp[j], dp[j+1]);//以(i,j)作为起点的最大路径
			}
		}
		//(2)进行深度优先遍历,获取最大值
		System.out.println(dp[0]);
	}
	
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值