【luogu P1040 加分二叉树】 题解
题目链接:https://www.luogu.org/problemnew/show/P1040
今天考试考了一个区间DP...没错就是这个...
太蒟了真是连区间DP都不会...看了看题解也看不懂,于是请了某獴dalao给补充了一下。
在这里把自己的理解写下来,算是给一些像我一样不会区间DP的萌新们一点指引。
所谓区间dp,顾名思义就是在一段区间上的动态规划。
它既要满足dp问题的最优子结构和无后效性外,还应该符合在区间上操作的特点。我们是用小区间的最优推出大区间的最优。
通常我们是拿f[i][j]表示区间i—j。在这个题中,我们就用f[i][j]表示区间i—j的最大权值。
对于区间DP,我们通常是一层循环枚举区间的长度,一层循环枚举区间的左端点。然后进行我们需要的DP就行了。
具体对这个题的做法代码里有注释。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n, v[31], f[31][31], root[31][31], l, r;
void print(int l, int r)
{
if(l > r) return;
printf("%d ",root[l][r]);
print(l, root[l][r]-1);
print(root[l][r]+1,r);
}
int main()
{
//freopen("binary.in","r",stdin);
//freopen("binary.out","w",stdout);
scanf("%d",&n);
for(int i = 1; i <= n; i++)
{
scanf("%d",&v[i]);
f[i][i] = v[i];//当只有自己的时候,最大就是自己
root[i][i] = i;//root[i][j]表示在区间i—j中,以哪个点作为根得到的权值最大。
}
for(int k = 2; k <= n; k++)//枚举区间大小
for(int l = 1; l+k-1 <= n; l++)//枚举区间内的端点
{
r = l+k-1;
if(f[l][r] < v[l]+f[l+1][r])
{
f[l][r] = v[l]+f[l+1][r];
root[l][r] = l;
}//右子树为空,只有左子树 的情况
if(f[l][r] < v[r]+f[l][r-1])
{
f[l][r] = v[r]+f[l][r-1];
root[l][r] = r;
}//左子树为空,只有右子树 的情况
for(int i = l+1; i <= r-1; i++)
{
if(f[l][i-1]*f[i+1][r]+v[i] > f[l][r])
{
f[l][r] = f[l][i-1]*f[i+1][r]+v[i];
root[l][r] = i;
}
}//左右子树均不为空
}//整个是在枚举在一段区间内,分别以每个点做根的情况
printf("%d\n",f[1][n]);//很明显我们所求的是1—n区间
print(1,n);//输出路径不多讲了
return 0;
}
【luogu P1040 加分二叉树】 题解的更多相关文章
- luogu P1040 加分二叉树
题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,-,n),其中数字1,2,3,-,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都 ...
- 洛谷P1040 加分二叉树题解
dp即可 \(f[i][j]\)表示i到j的加分 相当于区间dp了 #include<cstdio> using namespace std; int v[50]; int f[55][5 ...
- 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] 加分二叉树
洛谷题目链接:加分二叉树 题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,-,n),其中数字1,2,3,-,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di ...
- 洛谷P1040 加分二叉树(树形dp)
加分二叉树 时间限制: 1 Sec 内存限制: 125 MB提交: 11 解决: 7 题目描述 设一个n个节点的二叉树tree的中序遍历为(l,2,3,...,n),其中数字1,2,3,...,n ...
- 【算法•日更•第十期】树型动态规划&区间动态规划:加分二叉树题解
废话不多说,直接上题: 1580:加分二叉树 时间限制: 1000 ms 内存限制: 524288 KB提交数: 121 通过数: 91 [题目描述] 原题来自:NOIP 20 ...
随机推荐
- How to add more to Git Bash on Windows
How to add more to Git Bash on Windows Download the lastest wget binary for windows from https://ete ...
- 阿里云centos 7 中tomcat 自启动
这里我的tomcat的安装路径为 /usr/local/tomcat 1 为tomcat添加自启动参数 catalina.sh在执行的时候会调用同级路径下的setenv.sh来设置额外的环境变量,因此 ...
- php获取今日、昨日、上周、本月的起始时间戳和结束时间戳的方法
php 获取今日.昨日.上周.本月的起始时间戳和结束时间戳的方法,主要使用到了 php 的时间函数 mktime.下面首先还是直奔主题以示例说明如何使用 mktime 获取今日.昨日.上周.本月的起始 ...
- jQuery 文本插入和标签移动方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- python学习(四)--POST请求
from urllib import requestimport urllibimport re #网页版有道翻译是ajax的post请求. #浏览器请求地址http://fanyi.youdao.c ...
- Linux防火墙命令
linux 查看防火墙状态 1.查看防火墙状态 systemctl status firewalld firewall-cmd --state #查看默认防火墙状态(关闭后显示notrunning ...
- Spring课程 Spring入门篇 5-2 配置切面aspect
本节主要讲了在xml中配置切面的demo 1 解析 1.1 配置切面xml 1.2 配置切面xml 1.3 问:什么是动态代理? 2 代码演练 2.1 配置切面xml 1 解析 1.1 配置切面xml ...
- 重写Euqals & HashCode
package com.test.collection; import java.util.HashMap; import java.util.Map; /** * 重写equals & ha ...
- sparkpython
http://blog.csdn.net/ydq1206/article/details/51922148
- Vue项目中引入ElementUI
前提:创建好的vue项目. 1.安装ElementUI 转到项目根目录,输入命令:#cnpm install element-ui --save-dev 2.在 main.js 引入并注册 impor ...