普及练习场 深度优先搜索 加分二叉树
来源:互联网 发布:最大的整型数据 编辑:程序博客网 时间:2024/06/06 18:22
题目链接
题意理解
一开始的时候我以为,这棵树是固定的,是因为我把题目理解成了完全二叉树,后来发现不对。实际上结合第二个问题,求树的前序遍历,我们由结论“前序遍历和中序遍历可以确定一棵二叉树”,便可以知道,这题目应该是想我们确定一棵树。若一棵树的分数最多,则其左子树*右子树分数+根分数最大,这是题目所说的。对于左右子树,也可以使用相同的方法确定。二叉树的遍历是根在中间的,所以就是合并类的区间DP。哎说到底其实自己的树和DP都不是很会,不过这题进度先开着再说吧。。。
代码
import java.util.Scanner;public class Main { static final int maxn = 50; static final long min = -999999999; static int n; static int[] a = new int[maxn]; // dp[i][j]表示[i, j]内最大分数 static long[][] dp = new long[maxn][maxn]; static int[][] root = new int[maxn][maxn]; static void dfs(int x, int y) { if (root[x][y] != 0) { System.out.print(root[x][y] + " "); } if (root[x][root[x][y] - 1] != 0) { dfs(x, root[x][y] - 1); } if (root[root[x][y] + 1][y] != 0) { dfs(root[x][y] + 1, y); } } public static void main(String[] args) { for(int i = 0; i < maxn; i++) { a[i] = 0; } for(int i = 0; i < maxn; i++) { for(int j = 0; j < maxn; j++) { root[i][j] = 0; } } Scanner scanner = new Scanner(System.in); n = scanner.nextInt(); for(int i = 0; i <= n; i++) { for(int j = 0; j <= n; j++) { dp[i][j] = 1; } } for(int i = 1; i <= n; i++) { a[i] = scanner.nextInt(); dp[i][i] = a[i]; root[i][i] = i; } scanner.close(); for(int len = 1; len <= n; len++) { for(int i = 1; i <= n; i++) { int j = i + len; if(j <= n) { long temp = min; for(int k = i; k <= j; k++) { if(temp < (dp[i][k-1] * dp[k+1][j] + a[k])) { temp = dp[i][k-1] * dp[k+1][j] + a[k]; root[i][j] = k; } } dp[i][j] = temp; } } } System.out.println(dp[1][n]); dfs(1, n); }}
欢迎加入“不会算法一群菜鸟”,群号是⑥⑥①⑨②2025,这是我设置的一道很低的门槛用来阻止广告的。入群的验证暗号是:我爱编译原理
阅读全文