P1040 加分二叉树(区间DP)
解题思路
题目已经给出了树的中序遍历,因此我的想法是利用中序遍历的特点:若某子树的根结点为k,那么k之前的结点组成这一子树的左子树,k之后的结点组成这一子树的右子树,可以通过不断地枚举每个子树的根结点k,求出每个子树的最大加分:{ 左子树的最大加分*右子树的最大加分+ 根结点k的值}
以上是通过已知中序遍历想到是方法,结合已知条件,对于某一子树的中序遍历: {l, l + 1, ... , r} ,若根节点为k,那么 {l, l +1,...,k-1} 即为这一子树的左子树,{k+1,k+2,...,r}即为这一子树的右子树,因此,可以通过这种方法构造所有可能的树结构
根据上面的方法,我们通过递归求出每一段中序遍历{l,l+1,...,r}代表的子树的最大加分dp[l][r]以及根结点root[l][r],根据状态转移方程
dp[l][r] = max(dp[l][r],dp[l][k-1] + dp[k+1][r] + val[k]) { l <= k <= r}
并记录dp[l][r]取最大值时的根结点root[l][r],这样一来dp[1][n]即为我们所求的最大加分,又利用root和中序遍历求出前序遍历
代码区
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<string>
#include<fstream>
#include<vector>
#include<stack>
#include <map>
#include <iomanip> #define bug cout << "**********" << endl
#define show(x, y) cout<<"["<<x<<","<<y<<"] "
#define LOCAL = 1;
using namespace std;
typedef long long ll;
const ll inf = 1e18 + ;
const int mod = 1e9 + ;
const int Max = 1e5 + ; int n;
ll val[];
ll dp[][]; //表示[l,r]子树的最大加分
int root[][]; //表示[l,r]子树的根结点
//dp,root均为以[l,r]组成的子树的数据 ll dfs(int l, int r)
{
if (l > r) //空树
return ;
if(l == r) //叶子节点
return dp[l][r] = val[l]; if (dp[l][r] != -)
{
return dp[l][r];
} for (int k = l; k <= r; k++) //枚举子树[l,r]的根结点
{
ll now = dfs(l,k-) * dfs(k + , r) + val[k];
if(now > dp[l][r])
dp[l][r] = now,root[l][r] = k;
}
return dp[l][r];
} void dfs2(int l,int r)
{
if(l > r) //空树
return;
printf("%d ",root[l][r]);
dfs2(l,root[l][r] - );
dfs2(root[l][r] + , r);
} int main()
{
#ifdef LOCAL
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
scanf("%d", &n);
for (int i = ; i <= n; i++)
scanf("%lld", val + i),root[i][i] = i; memset(dp,-,sizeof(dp));
dfs(,n); printf("%lld\n",dp[][n]);
dfs2(,n);
printf("\n");
return ;
}
P1040 加分二叉树(区间DP)的更多相关文章
- 洛谷P1040 加分二叉树(区间dp)
P1040 加分二叉树 题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di, ...
- P1040 加分二叉树 区间dp
题目描述 设一个nn个节点的二叉树tree的中序遍历为(1,2,3,…,n1,2,3,…,n),其中数字1,2,3,…,n1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第ii个节 ...
- [Swust OJ 360]--加分二叉树(区间dp)
题目链接:http://acm.swust.edu.cn/problem/360/ Time limit(ms): 1000 Memory limit(kb): 65535 Description ...
- cogs 106. [NOIP2003] 加分二叉树(区间DP)
106. [NOIP2003] 加分二叉树 ★☆ 输入文件:jfecs.in 输出文件:jfecs.out 简单对比时间限制:1 s 内存限制:128 MB [问题描述] 设 一个 n ...
- 【洛谷】P1040 加分二叉树
[洛谷]P1040 加分二叉树 题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数 ...
- 【Luogu】P1040加分二叉树(区间DP)
题目链接 区间DP,因为中序遍历的性质:区间[l,r]的任何一个数都可以是该区间的根节点. 更新权值的时候记录区间的根节点,最后DFS输出. 见代码. #include<cstdio> # ...
- 洛谷P1040 加分二叉树(树形dp)
加分二叉树 时间限制: 1 Sec 内存限制: 125 MB提交: 11 解决: 7 题目描述 设一个n个节点的二叉树tree的中序遍历为(l,2,3,...,n),其中数字1,2,3,...,n ...
- [NOIP2003] 提高组 洛谷P1040 加分二叉树
题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都 ...
- P1040 加分二叉树
转自:(http://www.cnblogs.com/geek-007/p/7197439.html) 经典例题:加分二叉树(Luogu 1040) 设一个 n 个节点的二叉树 tree 的中序遍历为 ...
- 【luogu P1040 加分二叉树】 题解
题目链接:https://www.luogu.org/problemnew/show/P1040 今天考试考了一个区间DP...没错就是这个... 太蒟了真是连区间DP都不会...看了看题解也看不懂, ...
随机推荐
- Prometheus HA详解
Prometheus 横向扩展 当Exporter或者采集信息需要越来越多时就会考虑高可用,高可用优点不会因为集群中某个节点down而导致Prometheus不可用,可以让算力下沉; 缺点是A-Pro ...
- Maven的概述和基础(学习整理)
1. Maven是啥 Maven是一个项目管理工具,包含了一个项目对象模型(POM),一组标准集合,一个项目生命周期(Lifecycle),一个依赖管理系统,和用来运行定义在生命周期阶段中的插件目标的 ...
- form表单无刷新提交
Ajax最大的特点就是可以不刷新页面而实现数据的通信及更改页面信息.那么用AJAX进行后台通信传递字符串还是可以的,遇到上传文件该怎么办呢?基于安全考虑,JS是不能直接进行文件操作的,只好用原始的fr ...
- java课后实验性问题7
1.异常处理 import javax.swing.*; class AboutException { public static void main(String[] a) { int i = 1, ...
- java 设计模式 之 装饰器模式
装饰器模式的作用 在不修改原先对象核心的功能的情况下,对功能进行增强. 增强对象的功能的途径 通过类继承的方式,对父对象进行增强操作,例如造车是父类,改装跑车,跑车加大灯,改装房车,房车加私人电影院. ...
- based on Greenlets (via Eventlet and Gevent) fork 孙子worker 比较
Design — Gunicorn 19.9.0 documentationhttp://docs.gunicorn.org/en/stable/design.html#async-workers e ...
- Projects: Linux scalability: Accept() scalability on Linux 惊群效应
小结: 1.不必要的唤醒 惊群效应 https://github.com/benoitc/gunicorn/issues/792#issuecomment-46718939 https://www.c ...
- for-update与for-update nowait
1.for update 和 for update nowait 的区别: 首先一点,如果只是select 的话,Oracle是不会加任何锁的,也就是Oracle对 select 读到的数据不会有任何 ...
- Linux-命令与文件的查询
命令与文件的查询: 1.脚本文件名的查询: which(寻找执行文件) 命令格式: which [-a] command -a:列出查询到的所有命令的路径 2.文件名的查找: whereis.loca ...
- Qt编写安防视频监控系统12-异形布局
一.前言 视频监控系统中,除了常规的1画面.4画面.9画面.16画面以外,还有几个布局比较另类,比如6画面.8画面.13画面,有些通道需要占据不同的行列,4画面.9画面.16画面都是非常对称的布局,行 ...