个人认为比较好的(高端)树形DP,也有可能是人傻

3227: [Sdoi2008]红黑树(tree)

Time Limit: 10 Sec Memory Limit: 128 MB

Submit: 158 Solved: 96

[Submit][Status][Discuss]

Description

  红黑树是一类特殊的二叉搜索树,其中每个结点被染成红色或黑色。若将二叉搜索树结点中的空指针看作是指向一个空结点,则称这类空结点为二叉搜索树的前端结点。并规定所有前端结点的高度为-1。

  一棵红黑树是满足下面“红黑性质”的染色二叉搜索树:

  (1) 每个结点被染成红色或黑色;

  (2) 每个前端结点为黑色结点;

  (3) 任一红结点的子结点均为黑结点;

  (4) 在从任一结点到其子孙前端结点的所有路径上具有相同的黑结点数。

  从红黑树中任一结点x出发(不包括结点x),到达一个前端结点的任意一条路径上的黑结点个数称为结点x的黑高度,记作bh(x)。红黑树的黑高度定义为其根结点的黑高度。

  给定正整数N,试设计一个算法,计算出在所有含有N个结点的红黑树中,红色内结点个数的最小值和最大值。

Input

  输入共一个数N。

Output

  输出共两行。

  第一行为红色内结点个数的最小值,第二行为最大值。

Sample Input

8

Sample Output

1

4

HINT

对于 100% 的数据,1≤N≤5000

Source

这道题啊,想了很久,也调了挺长时间的;
中间请求Claris的帮助,可是Claris说太久没看这道了,记不太清细节了,于是我要了他的代码。。。
Claris早期的代码风格不认直视啊我的天!

题解:

令f【i】【j】【0,1】表示 包含i个非前端节点的节点,黑高度为j的,红根/黑根 红黑树中的最小/最大红节点数。

于是得到转移:

f[i][j][0]=min/max(f[i][j][0],f[k][j-1][1]+f[i-k-1][j-1][1]+1);

f[i][j][1]=min/max(f[i][j][1],min/max(f[k][j-1][1]+f[i-k-1][j-1][1],min/max(f[k][j][0]+f[i-k-1][j][0],f[k][j][0]+f[i-k-1][j-1][1])));

然后做好初始化即可;

code:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
} #define maxn 6020
int n;
int f[maxn][32][2];
int maxans,minans; int main()
{
n=read();
maxans=-0x7fffffff;minans=0x7fffffff;
memset(f,0x3f,sizeof f);
f[1][1][0]=1;f[1][1][1]=0;f[2][1][1]=1;
for (int i=1; i<=n; i++)
for (int j=1; j<=i; j++)
if (1<<j > n<<2) break; else
for (int k=0; k<=i-2; k++)
{
f[i][j][0]=min(f[i][j][0],f[k][j-1][1]+f[i-k-1][j-1][1]+1);
f[i][j][1]=min(f[i][j][1],min(f[k][j-1][1]+f[i-k-1][j-1][1],
min(f[k][j][0]+f[i-k-1][j][0],f[k][j][0]+f[i-k-1][j-1][1])));
}
for (int i=0; i<=30; i++)
minans=min(min(minans,f[n][i][0]),f[n][i][1]);
printf("%d\n",minans);
memset(f,-0x3f,sizeof f);
f[1][1][0]=1;f[1][1][1]=0;f[2][1][1]=1;
for (int i=1; i<=n; i++)
for (int j=1; j<=i; j++)
if (1<<j > n<<2) break; else
for (int k=0; k<=i-2; k++)
{
f[i][j][0]=max(f[i][j][0],f[k][j-1][1]+f[i-k-1][j-1][1]+1);
f[i][j][1]=max(f[i][j][1],max(f[k][j-1][1]+f[i-k-1][j-1][1],
max(f[k][j][0]+f[i-k-1][j][0],f[k][j][0]+f[i-k-1][j-1][1])));
}
for (int i=0; i<=30; i++)
maxans=max(max(maxans,f[n][i][0]),f[n][i][1]);
printf("%d\n",maxans);
return 0;
}

BZOJ-3227 红黑树(tree) 树形DP的更多相关文章

  1. BZOJ.3227.[SDOI2008]红黑树tree(树形DP 思路)

    BZOJ orz MilkyWay天天做sxt! 首先可以树形DP:\(f[i][j][0/1]\)表示\(i\)个点的子树中,黑高度为\(j\),根节点为红/黑节点的最小红节点数(最大同理). 转移 ...

  2. BZOJ 3227: [Sdoi2008]红黑树(tree)

    BZOJ 3227: [Sdoi2008]红黑树(tree) 标签(空格分隔): OI-BZOJ OI-其它 Time Limit: 10 Sec Memory Limit: 128 MB Descr ...

  3. [BZOJ 4033] [HAOI2015] T1 【树形DP】

    题目链接:BZOJ - 4033 题目分析 使用树形DP,用 f[i][j] 表示在以 i 为根的子树,有 j 个黑点的最大权值. 这个权值指的是,这个子树内部的点对间距离的贡献,以及 i 和 Fat ...

  4. [BZOJ 4455] [ZJOI 2016] 小星星 (树形dp+容斥原理+状态压缩)

    [BZOJ 4455] [ZJOI 2016] 小星星 (树形dp+容斥原理+状态压缩) 题面 给出一棵树和一个图,点数均为n,问有多少种方法把树的节点标号,使得对于树上的任意两个节点u,v,若树上u ...

  5. 熟练剖分(tree) 树形DP

    熟练剖分(tree) 树形DP 题目描述 题目传送门 分析 我们设\(f[i][j]\)为以\(i\)为根节点的子树中最坏时间复杂度小于等于\(j\)的概率 设\(g[i][j]\)为当前扫到的以\( ...

  6. [BZOJ 3227] [SDOI 2008] 红黑树(tree)

    Description 红黑树是一类特殊的二叉搜索树,其中每个结点被染成红色或黑色.若将二叉搜索树结点中的空指针看作是指向一个空结点,则称这类空结点为二叉搜索树的前端结点.并规定所有前端结点的高度为- ...

  7. Bzoj3227 [Sdoi2008]红黑树(tree)

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 204  Solved: 125 Description 红黑树是一类特殊的二叉搜索树,其中每个结点被染 ...

  8. hdu-5834 Magic boy Bi Luo with his excited tree(树形dp)

    题目链接: Magic boy Bi Luo with his excited tree Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: ...

  9. CF 461B Appleman and Tree 树形DP

    Appleman has a tree with n vertices. Some of the vertices (at least one) are colored black and other ...

  10. codeforces 161D Distance in Tree 树形dp

    题目链接: http://codeforces.com/contest/161/problem/D D. Distance in Tree time limit per test 3 secondsm ...

随机推荐

  1. HDU 1878 欧拉回路

    并查集水题. 一个图存在欧拉回路的判断条件: 无向图存在欧拉回路的充要条件 一个无向图存在欧拉回路,当且仅当该图所有顶点度数都是偶数且该图是连通图. 有向图存在欧拉回路的充要条件 一个有向图存在欧拉回 ...

  2. Unity3D面试题汇总

    1.请描述游戏动画有哪几种,以及其原理. 2.alpha blend 工作原理 3.写光照计算中的diffuse的计算公式 4.lod是什么,优缺点是什么 5.两种阴影判断的方法工作原理 6.MipM ...

  3. eclipse点击一个变量使相同名称变量高亮显示的方法

    preferences->java->Editor->Mark Occurences 选择最上的复选框,下面的就有很多了. 其中的Local variables就是变量的高亮显示.

  4. C/C++ 常用工具集

    1. c++filt  //注意:就是这个名字 "c++file". 能把c++的函数签名转换成代码形参格式: 如:# c++filt _ZNSt4priv17_Rb_tree_i ...

  5. Android service ( 一 ) 三种开启服务方法

    一. Service简介 Service是android 系统中的四大组件之一(Activity.Service.BroadcastReceiver.ContentProvider),它跟 Activ ...

  6. javascript中的栈结构

    1.栈的定义 栈是一种和列表类似的数据结构,可以用它来解决很多的编程问题,栈是一种高效的数据结构,因为数据只能在栈的顶端添加或者删除,所以这样的操作很快而且容易实现. 栈是一种特殊的列表,站内的元素只 ...

  7. 02SpringMvc_springmvc快速入门小案例(XML版本)

    这篇文章中,我们要写一个入门案例,去整体了解整个SpringMVC. 先给出整个项目的结构图:

  8. [资料]Nginx做IP访问限制以及正则规则

    nginx配置location总结及rewrite规则写法 Nginx Location配置总结 Nginx 禁止某个IP访问 server { listen 443; root /webroot/; ...

  9. Sublime 将 Tab 转为空格

    最近在使用 vue-cli 搭建项目,但每次用 Hbuilder 编写 vue 文件的时候,如果存在<script>部分就会报错,错误信息大意是说空格有问题.仔细研究了之后才知道,这是因为 ...

  10. AWS S3使用小结

    使用场景一:储存网站的图片,并能被任何人访问 1. 创建一个bucket,名字与需要绑定的域名一致. 例如,根域名是mysite.com,希望把所有图片放在pic.mysite.com下面,访问的时候 ...