zoukankan      html  css  js  c++  java
  • 加分二叉树

    加分二叉树

    Description

    设一个n个节点的二叉树tree的中序遍历为(l,2,3,…,n),其中数字1,2,3,…,n为节点编号。每个节点都有一个分数(均为正整数),记第j个节点的分数为di,tree及它的每个子树都有一个加分,任一棵子树subtree(也包含tree本身)的加分计算方法如下:subtree的左子树的加分× subtree的右子树的加分+subtree的根的分数 若某个子树为空,规定其加分为1,叶子的加分就是叶节点本身的分数。不考虑它的空子树。

    试求一棵符合中序遍历为(1,2,3,…,n)且加分最高的二叉树tree。要求输出:

    (1)tree的最高加分

    (2)tree的前序遍历

    Input

    第1行:一个整数n(n<30)为节点个数。 第2行:n个用空格隔开的整数,为每个节点的分数(分数<100)。

    Output

    第1行:一个整数,为最高加分(结果不会超过4,000,000,000)。 第2行:n个用空格隔开的整数,为该树的前序遍历。

    Sample Input

    5
    5 7 1 2 10
    

    Sample Output

    145	
    3 1 2 4 5
    

    HINT

    Source

    #include <bits/stdc++.h>
    using namespace std;
    int n, a[101];
    int opt[101][101];
    int f[101][101];
    int solve (int p, int q) {
    	if (f[p][q] != -1) {
    		return f[p][q];
    	}
    	if (p > q) {
    		f[p][q] = 1;
    		return 1;
    	}
    	else if (p == q) {
    		opt[p][p] = p;
    		f[p][q] = a[p];
    		return f[p][q];
    	}
    	int ans = 0;
    	for (int r = p; r <= q; r ++) {
    		int res = solve(p, r - 1) * solve(r + 1, q) + a[r];
    		if (res > ans) {
    			ans = res;
    			opt[p][q] = r;
    		}
    	}
    	f[p][q] = ans;
    	return f[p][q];
    }
    void proot(int p, int q) {
    	if (p > q) {
    		return ;
    	}
    	printf("%d ", opt[p][q]);
    	proot(p, opt[p][q] - 1);
    	proot(opt[p][q] + 1, q);
    }
    int main() {
    	cin >> n;
    	memset(f, -1, sizeof(f));
    	for (int i = 1; i <= n; i ++) {
    		scanf("%d", &a[i]);
    	}
    	cout << solve(1, n) << endl;
    	proot(1, n);
    	return 0;
    }
    

    递归写法

    #include <bits/stdc++.h>
    using namespace std;
    int n, a[101];
    int opt[101][101];
    int f[101][101];
    void print(int p, int q) {
    	if (p > q) return ;
    	printf ("%d ", opt[p][q]);
    	print(p, opt[p][q] - 1);
    	print(opt[p][q] + 1, q);
    }
    int main() {
    	cin >> n;
    	memset(f, -1, sizeof(f));
    	for (int i = 1; i <= n; i ++) {
    		scanf("%d", &a[i]);
    		f[i][i] = a[i];
    		f[i][i - 1] = 1;
    		opt[i][i] = i;
    	}
    	for (int len = 2; len <= n; len ++) {
    		for (int i = 1; i <= n; i ++) {
    			int j = i + len - 1;
    			for (int k = i; k <= j; k ++) {
    				if (f[i][j] < f[i][k - 1] * f[k + 1][j] + a[k]) {
    					f[i][j] = f[i][k - 1] * f[k + 1][j] + a[k];
    					opt[i][j] = k;
    				}
    			}
    		}
    	}
    	cout << f[1][n] << endl;
    	print(1, n);
    	return 0;
    }
    
  • 相关阅读:
    Java 下载网络资源
    Java11 ThreadLocal的remove()方法源码分析
    软件测试的术语SRS,HLD,LLD,BD,FD,DD意义
    2020年12月2日
    20201129
    2020年11月28日
    程序员的三门课
    中间件到底是个什么鬼东西?
    接口测试框架的形成过程
    一个字符到底等于多少字节
  • 原文地址:https://www.cnblogs.com/LJA001162/p/11922071.html
Copyright © 2011-2022 走看看