luogu P1040 加分二叉树
题目描述
设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号。每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都有一个加分,任一棵子树subtree(也包含tree本身)的加分计算方法如下:
subtree的左子树的加分× subtree的右子树的加分+subtree的根的分数。
若某个子树为空,规定其加分为1,叶子的加分就是叶节点本身的分数。不考虑它的空子树。
试求一棵符合中序遍历为(1,2,3,…,n)且加分最高的二叉树tree。要求输出;
(1)tree的最高加分
(2)tree的前序遍历
输入输出格式
输入格式:
第1行:一个整数n(n<30),为节点个数。
第2行:n个用空格隔开的整数,为每个节点的分数(分数<100)。
输出格式:
第1行:一个整数,为最高加分(结果不会超过4,000,000,000)。
第2行:n个用空格隔开的整数,为该树的前序遍历。
输入输出样例
输入样例#1:
5
5 7 1 2 10
输出样例#1: 复制
145
3 1 2 4 5
dp[i][j]表示区间i到j所能产生的最大贡献
#include<cstdio>
#include<iostream>
using namespace std;
const int maxn = 106;
int midtree[maxn];
int n;
int dp[maxn][maxn];
inline int read() {
int x = 0,f = 1;char c = getchar();
while(c < '0' || c > '9') {
if(c == '-')f = -1;
c = getchar();
}
while(c <= '9' && c>= '0') x = x*10+c-'0',c = getchar();
return x*f;
}
int root[42][42];
void print(int l,int r) {
if(l>r)return;
if(l==r){
printf("%d ",l);
return ;
}
printf("%d ",root[l][r]);
int mid=root[l][r];
print(l,mid-1);
print(mid+1,r);
}
int main() {
n=read();
for(int i=1;i<=n;++i)
midtree[i] = read(),dp[i][i]=midtree[i],root[i][i]=i;
for(int i=1;i<=n+1;++i) {
dp[i][i-1]=1;
}
for(int i=n;i>=1;--i)
{
for(int j=i+1;j<=n;++j)
{
for(int k=i;k<=j;++k)
{
if(dp[i][j]<midtree[k]+dp[i][k-1]*dp[k+1][j])
{
root[i][j]=k;
dp[i][j]=midtree[k]+dp[i][k-1]*dp[k+1][j];
}
}
}
}
printf("%d\n",dp[1][n]);
print(1,n);
return 0;
}
luogu P1040 加分二叉树的更多相关文章
- 【luogu P1040 加分二叉树】 题解
题目链接:https://www.luogu.org/problemnew/show/P1040 今天考试考了一个区间DP...没错就是这个... 太蒟了真是连区间DP都不会...看了看题解也看不懂, ...
- CJOJ 1010【NOIP2003】加分二叉树 / Luogu 1040 加分二叉树(树型动态规划)
CJOJ 1010[NOIP2003]加分二叉树 / Luogu 1040 加分二叉树(树型动态规划) Description 设 一个 n 个节点的二叉树 tree 的中序遍历为( 1,2,3,-, ...
- 【洛谷】P1040 加分二叉树
[洛谷]P1040 加分二叉树 题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数 ...
- 洛谷P1040 加分二叉树(区间dp)
P1040 加分二叉树 题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di, ...
- P1040 加分二叉树
转自:(http://www.cnblogs.com/geek-007/p/7197439.html) 经典例题:加分二叉树(Luogu 1040) 设一个 n 个节点的二叉树 tree 的中序遍历为 ...
- 洛谷P1040 加分二叉树(树形dp)
加分二叉树 时间限制: 1 Sec 内存限制: 125 MB提交: 11 解决: 7 题目描述 设一个n个节点的二叉树tree的中序遍历为(l,2,3,...,n),其中数字1,2,3,...,n ...
- [洛谷P1040] 加分二叉树
洛谷题目链接:加分二叉树 题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,-,n),其中数字1,2,3,-,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di ...
- 【Luogu】P1040加分二叉树(区间DP)
题目链接 区间DP,因为中序遍历的性质:区间[l,r]的任何一个数都可以是该区间的根节点. 更新权值的时候记录区间的根节点,最后DFS输出. 见代码. #include<cstdio> # ...
- 洛谷P1040 加分二叉树【记忆化搜索】
题目链接:https://www.luogu.org/problemnew/show/P1040 题意: 某一个二叉树的中序遍历是1~n,每个节点有一个分数(正整数). 二叉树的分数是左子树分数乘右子 ...
随机推荐
- perl-basic-数组操作
RT...直接看代码 my @stack = ("Fred", "Eileen", "Denise", "Charlie" ...
- 利用for循环和range输出9 * 9乘法口诀表
li = [2, 3, 4, 5, 6, 7, 8, 9, 10] for i in li: for j in range(1, i): print('{0} * {1} = {2}'.format( ...
- 2018 Multi-University Training Contest 10 CSGO(HDU - 6435)(最远曼哈顿距离)
有 n 种主武器,m 种副武器.每种武器有一个基础分数k种属性值 X[i] . 选出一种主武器 mw 和一种副武器 sw,使得两种武器的分数和 + 每个属性的差值尽量大.(参考下面的式子) 多维的最远 ...
- POJ:1904-King's Quest
King's Quest Time limit15000 ms Case time limit2000 ms Memory limit65536 kB Description Once upon a ...
- re--参考手册
表达式全集 字符 描述 \ 将下一个字符标记为一个特殊字符.或一个原义字符.或一个向后引用.或一个八进制转义符.例如,“n”匹配字符“n”.“\n”匹配一个换行符.串行“\\”匹配“\”而“\(”则匹 ...
- luogu3178 [HAOI2015]树上操作
裸题 #include <iostream> #include <cstdio> using namespace std; typedef long long ll; int ...
- AtCoder Grand Contest 020
A - Move and Win Time limit : 1sec / Memory limit : 512MB Score : 300 points Problem Statement A gam ...
- Map容器——HashMap及常用API,及put,get方法解析,哈希码的产生和使用
Map接口 ① 映射(map)是一个存储键/值对的对象.给定一个键,可以查询到它的值,键和值都是对象; ② 键必须是唯一的,值可以重复; ③ 有些映射可以接收null键和null值,而有的 ...
- js版本下拉菜单
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
- redhat linux 从/home目录扩展空间至/根目录
查看分区大小 [root@easdb01 ~]# df -hFilesystem Size Used Avail Use% Mounted on/dev/mapper/vg_easdb01-lv_ro ...