码迷,mamicode.com
首页 > 其他好文 > 详细

P1040 加分二叉树

时间:2020-06-28 22:52:19      阅读:90      评论:0      收藏:0      [点我收藏+]

标签:return   证明   lan   max   bit   为什么   space   std   efi   

P1040 加分二叉树

这是一个区间DP。
本题有一个一开始令我疑惑的点:为什么在第23行,这种解法只考虑了左子树为空的情况?后来想了想,觉得可能有两个原因。

  1. 如果某一个节点之下有两个及以上的节点的话,左右子树不为空的情况一定比有一个子树为空的情况要优。第23行代码只是针对根节点下只有一个节点的情况。
  2. 左子树为空和右子树为空这两种情况实际上是相同的(根节点的加分相同。)
    第一点我不知道如何证明。或许我的理解是错误的,还请路过的大佬不吝赐教。
#include<bits/stdc++.h>
using namespace std;
#define ll long long 
ll a[40],d[40][40],n,root[40][40]; 
void print(ll l,ll r){
	if(l > r) return;
	cout << root[l][r] << " ";
	if(l == r) return;
	print(l,root[l][r] - 1);
	print(root[l][r] + 1,r);
}
int main(){
	cin >> n;
	for(int i = 1; i <= n; i++){
		cin >> a[i];
		d[i][i] = a[i];	
		root[i][i] = i;
	}
	ll maxn = 0;
	for(int l = 2; l <= n; l++)
		for(int i = 1; i + l - 1 <= n; i++){
			int j = i + l - 1;
			d[i][j] = d[i + 1][j] + d[i][i]; //假如左子树为空
			root[i][j] = i; 
			for(int k = i + 1 ; k < j; k++){ //枚举左右子树的中间断点
				if(d[i][j] < d[i][k - 1] * d[k + 1][j] + d[k][k]){
					d[i][j] = d[i][k - 1] * d[k + 1][j] + d[k][k];
					maxn = max(maxn,d[i][j]);
					root[i][j] = k; //记录根节点,用于输出方案
				}
			}
		} 
	cout << maxn << endl;
	print(1,n);
	return 0;
} 

P1040 加分二叉树

标签:return   证明   lan   max   bit   为什么   space   std   efi   

原文地址:https://www.cnblogs.com/FoxC/p/13205007.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!