题目链接: https://vijos.org/p/1100

题目大意:NOIP著名的加分二叉树。给出一棵树的中序遍历,加分规则左子树*右子树+根。空子树分数为1。问最大加分的树结构,输出树结构的先序遍历。

解题思路

先从小的问题看起。

对于一棵子树,只要知道根是啥,就能轻松求出这棵子树的加分情况。

那么就变成枚举根的区间DP问题。

由于要输出先序遍历,则用m[i][j]记录在i~j区间选择的根。

区间DP边界:

①一个点情况:即无左右子树,dp[i][i]=node[i],m[i][i]=i.

②两个点情况,即无右子树。dp[i][i+1]=node[i]+node[i+1];m[i][i+1]=i。

注意为什么DP边界是两种情况,是因为区间DP枚举中间分割点时,是按照常规处理左区间和右区间的,以上两种情况,左右区间都是有问题的。

所以需要特别预处理。

区间DP:

推荐先枚举区间间隔p的写法,这里直接从p=2开始计算。p=0,p=1已经预处理。

对于dp[i][j],则根k的范围(i+1,j),按照规则写方程就行了。m[i][j]=k,记录每个区间的根。

则最后ans=dp[1][n]。

递归打印方案,先序遍历是根左右,不要打错了。

#include "cstring"
#include "cstdio"
#include "cstring"
int dp[31][31],m[31][31],node[31];
void print(int i,int j)
{printf("%d ",m[i][j]);if(i<=m[i][j]-1) print(i,m[i][j]-1);if(m[i][j]+1<=j) print(m[i][j]+1,j);
}
int main()
{//freopen("in.txt","r",stdin);int n;while(scanf("%d",&n)!=EOF){memset(dp,0,sizeof(dp));for(int i=1; i<=n; i++) scanf("%d",&node[i]);for(int i=1; i<=n; i++){dp[i][i]=node[i];m[i][i]=i;dp[i][i+1]=node[i]+node[i+1];m[i][i+1]=i;}for(int p=2; p<=n; p++){for(int i=1; i<=n; i++){int j=i+p;if(j>n) break;dp[i][j]=1;for(int k=i+1; k<j; k++){if((dp[i][k-1]*dp[k+1][j]+node[k])>dp[i][j]){dp[i][j]=dp[i][k-1]*dp[k+1][j]+node[k];m[i][j]=k;}}}}printf("%d\n",dp[1][n]);print(1,n);}
}

转载于:https://www.cnblogs.com/neopenx/p/4048850.html

Vijos 1100 (区间DP)相关推荐

  1. 编程之美2015资格赛 题目2 : 回文字符序列 [ 区间dp ]

    传送门 题目2 : 回文字符序列 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定字符串,求它的回文子序列个数.回文子序列反转字符顺序后仍然与原序列相同.例如字符串ab ...

  2. bzoj 1710: [Usaco2007 Open]Cheappal 廉价回文【区间dp】

    只要发现添加一个字符和删除一个字符是等价的,就是挺裸的区间dp了 因为在当前位置加上一个字符x就相当于在他的对称位置删掉字符x,所以只要考虑删除即可,删除费用是添加和删除取min 设f[i][j]为从 ...

  3. POJ 2955 Brackets (区间DP)

    题目链接:http://poj.org/problem?id=2955 Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submiss ...

  4. 0x53. 动态规划 - 区间DP(习题详解 × 8)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 文章目录 0x53. 动态规划 - 区间DP Problem A. 最优矩阵链乘 Problem B. ...

  5. UVA1626 括号序列 Brackets sequence(区间DP匹配括号,输出匹配方案)

    整理的算法模板合集: ACM模板 UVA1626 Brackets sequence 我们将正规括号序列定义如下: 空序列是正规括号序列. 如果 SSS 是一个正规括号序列,那么 (S) 和 [S] ...

  6. UVA10003 切木棍 Cutting Sticks(区间DP、细节)

    整理的算法模板合集: ACM模板 本题其实就是一个区间DP 的模板题,总长度为len,有n个切割点,也就是说能被切割成n+1段,所以左边界是0,有边界是n + 1,所以答案就是f[0][n + 1]. ...

  7. 【动态规划】区间DP - 最优矩阵链乘(另附POJ1651Multiplication Puzzle)

    最优矩阵链乘(动态规划) 一个n∗mn*mn∗m的矩阵由 nnn 行 mmm 列共 n∗mn*mn∗m 排列而成.两个矩阵A和B可以相乘当且仅当A的列数等于B的行数.一个nm的矩阵乘mp的矩阵,运算量 ...

  8. 【每日DP】day13、P3147 [USACO16OPEN]262144 (区间DP,2048游戏)难度⭐⭐⭐★

    P3147 [USACO16OPEN]262144 P 想到合并,自然就想到区间dp,一个被合成的数之前是一个区间,并且由两个数比它小 111 的区间合成.可麻烦的是,我们并不知道之前的两个区间长度各 ...

  9. poj1651(区间dp)

    题目连接:http://poj.org/problem?id=1651 题意:给出一组N个数,每次从中抽出一个数(第一和最后一个不能抽),该次的得分即为抽出的数与相邻两个数的乘积.直到只剩下首尾两个数 ...

最新文章

  1. 设计模式--享元(Flyweight)模式
  2. 事件绑定、事件监听、事件委托
  3. C语言中的EOF符号常量
  4. python idle退出_【ZZ】windows+python2.7在IDLE中执行sys.exit()出现的问题及解决方案
  5. VTK嵌入MFC同步显示
  6. 用turtle画皮卡丘
  7. ElasticSearch Java SpringBoot根据时间范围分组求和
  8. Oracle 11g的安装详细过程
  9. JAVA线程池_并发队列工作笔记0002---认识线程池_在线程池中使用队列
  10. Since WWDC released the first developer
  11. 如何在Windows上使用GIT下载Android源代码
  12. javaweb JAVA JSP学生考勤管理系统考勤管理系统jsp学生迟到早退考勤查询系统(考勤管理系统源码)
  13. CentOS 安装JDK8
  14. (原创)windows10cmd装逼命令
  15. 【物联网控制技术复习】【复数的概念】【拉普拉斯变换】
  16. 电脑关机后键盘灯和风扇还在转的解决方案
  17. amazeui验证遇到的坑
  18. 教你有效清理C盘空间不足的方法
  19. Pegasus Serial Port Tool @ Simplicity Version 串口测试工具简化版发布
  20. win11家庭版设置远程桌面

热门文章

  1. 三维位姿:***图像特征-特征提取-姿态估计
  2. Allegro PCB Design GXL (legacy) 由零散的对象构成一个Shape
  3. Selenium2 Python 自己主动化測试实战学习笔记(五)
  4. PC远程调试移动设备
  5. python之字典使用方法总结
  6. Android 一s个相对完整的自动升级功能实现代码
  7. 别忘记今天是父亲节六盘水
  8. js弹出窗体获得焦点
  9. [导入]Ms Ajax Lib- Object 类型扩展
  10. springboot 系列教程十:springboot单元测试