SJTU 1077 加分二叉树
http://acm.sjtu.edu.cn/OnlineJudge/problem/1077
题意:
设一个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的前序遍历
分析:
1.题目中明确要求生成的树其中序遍历为1,2,3....n,根据这个我们可以知晓对于a1,a2,a3,a4...ai....an来说,若ai为根,则a1,a2....ai-1在为ai的左子树,ai+1....an为ai的右子树,所以这给我们进行区间动态规划成为了可能
2.区间动态规划,用递归进行书写简单且易于理解
3.路径的记忆,定义一个路径数组,若更新dp值得时候,也更新路径的根节点
4.路径打印,由于要求前序遍历,所以先输出,再分别递归左子树,右子树
5.错误点:在书写代码的时候,DFS(x,i-1)*DFS(i+1,y),书写太粗心写漏了一个DFS,导致debug了很久都没有找出错误来。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL long long
const int INF=0x7fffffff;
const int MN=;
LL dp[MN][MN];
int path[MN][MN];
int num[MN];
int n;
int flag; LL DFS(int x,int y)
{
if(x>y)
{
path[x][y]=;
return dp[x][y]=;
}
if(dp[x][y]!=-) return dp[x][y];
if(x==y)
{
path[x][y]=x;
return dp[x][x]=num[x];
}
dp[x][y]=;
for(int i=x; i<=y; i++)
{
DFS(x,i-);
DFS(i+,y);
if(dp[x][i-]*dp[i+][y]+num[i]>dp[x][y])
{
dp[x][y]=dp[x][i-]*dp[i+][y]+num[i];
path[x][y]=i;
}
}
return dp[x][y];
} void Print(int x,int y)
{
if(x>y) return ;
if(flag) printf(" ");
flag=;
printf("%d",path[x][y]);
Print(x,path[x][y]-); Print(path[x][y]+,y);
} int main()
{
int i,j;
while(scanf("%d",&n)!=EOF)
{
flag=;
memset(dp,-,sizeof(dp));
for(i=; i<=n; i++)
scanf("%d",&num[i]);
DFS(,n);
printf("%lld\n",dp[][n]);
Print(,n);
printf("\n");
}
return ;
}
SJTU 1077 加分二叉树的更多相关文章
- CODEVS1090 加分二叉树
codevs1090 加分二叉树 2003年NOIP全国联赛提高组 题目描述 Description 设一个n个节点的二叉树tree的中序遍历为(l,2,3,…,n),其中数字1,2,3,…,n为节点 ...
- NOIP2003加分二叉树[树 区间DP]
题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都 ...
- Vijos 1100 加分二叉树
题目 1100 加分二叉树 2003年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目描述 Description 设一个n个节点的二叉树tree的中序遍历为( ...
- CJOJ 1010【NOIP2003】加分二叉树 / Luogu 1040 加分二叉树(树型动态规划)
CJOJ 1010[NOIP2003]加分二叉树 / Luogu 1040 加分二叉树(树型动态规划) Description 设 一个 n 个节点的二叉树 tree 的中序遍历为( 1,2,3,-, ...
- 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 加分二叉树
[洛谷]P1040 加分二叉树 题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数 ...
- 【题解】NOI2009二叉查找树 + NOIP2003加分二叉树
自己的思维能力果然还是太不够……想到了这棵树所有的性质即中序遍历不变,却并没有想到怎样利用这一点.在想这道题的过程中走入了诸多的误区,在这里想记录一下 & 从中吸取到的教训(原该可以避免的吧) ...
- [洛谷P1040] 加分二叉树
洛谷题目链接:加分二叉树 题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,-,n),其中数字1,2,3,-,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di ...
随机推荐
- [LeetCode]9. Palindrome Number回文数
Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same back ...
- JS 获取 今日、昨日、本周、本月、本季度、本年、上月、上周、上季度、去年
/** * 日期范围工具类 */ var dateRangeUtil = (function () { /*** * 获得当前时间 */ this.getCurrentDate = function ...
- 全面理解HTTP协议
引言:作为一名软件工程Web专业学生,对于HTTP的熟悉掌握是必不可少的,特此做记录,打造自己的HTTP栈. URL与URI 我们经常接触到的就是URL了,它就是我们访问web的一个字符串地址,那么U ...
- sql & sqlalchemy join多个表
# 连接两个数据表的用法: FROM Member INNER JOIN MemberSort ON Member.MemberSort=MemberSort.MemberSort # 语法格式可以概 ...
- Altera FFT核使用详解
简介 快速傅里叶变换(Fast Fourier Transform)最为一种高效的算法,被广泛的用于信号处理与数据分析等领域.对于设计工程师来讲,自己动手采样可编程语言来实现一个FFT/IFFT模块, ...
- Java 集合框架_上
集合框架被设计成要满足以下几个目标. 该框架必须是高性能的.基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的. 该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性. 对一个集合的 ...
- find - 递归地在层次目录中处理文件
总览 SYNOPSIS find [path...] [expression] 描述 DESCRIPTION 这个文档是GNU版本 find 命令的使用手册. find 搜索目录树上的每一个文件名,它 ...
- 用virtualenv构建一个新的python环境,这个新的环境在这个创建的文件夹下
http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143271210830032 ...
- bootstrap3 文档随看
唉 昨天看的是2,早知道就只可以看3啦,虽然整体不变,但是小改小闹的还是很多啦.产品上线是需要升级的,但是像这么改会很烦哎,有些样式名字修改,用法修改,功能修改,那让用惯了2的人还得把之前记忆清除了然 ...
- eclipse 导出Runnable JAR file ,双击无法执行原因与解决 双击后闪退的原因 批处理java打包文件 @echo off start javaw -jar *.jar
eclipse 导出Runnable JAR file 导出后如果系统没有JRE,双击无法运行,需要用命令方法 安装后解决,如图 双击后闪退的原因,通过执行 java -jar TingGe.jar ...