【树形DP】三色二叉树

标签(空格分隔): 树形DP


【题目】

一棵二叉树可以按照如下规则表示成一个由0、1、2组成的字符序列,我们称之为“二叉树序列S”:

0 该树没有子节点 1S1 该树有一个子节点,S1为其二叉树序列 1S1S2 该树有两个子节点,S1,S2分别为两个二叉树的序列 例如,下图所表示的二叉树可以用二叉树序列S=21200110来表示。

你的任务是要对一棵二叉树的节点进行染色。每个节点可以被染成红色、绿色或蓝色。并且,一个节点与其子节点的颜色必须不同,如果该节点有两个子节点,那么这两个子节点的颜色也必须不相同。给定一棵二叉树的二叉树序列,请求出这棵树中最多和最少有多少个点能够被染成绿色。

输入格式

输入文件仅有一行,不超过10000个字符,表示一个二叉树序列

输出格式

输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色。

样例输入

1122002010

样例输出

5 2

【思路】

(想是好想,调是真难调)

1.题目中又让输出最多又让输出最小的,一看就要开2个数组,一个存最大,一个存最小,f[u][]表示以u为根节点的最大绿节点,d[u][]表示以u为根节点的最小绿节点

2.每个节点可以是三种颜色中的一种,根据我们之前写过的小胖守皇宫和没有上司的舞会,很容易想到用三个状态分别表示三个颜色,这题我是以0做绿,1-红,2-蓝

3.建树是个头疼的问题,细细搞♂了搞题目,这个序列有一个显著特点:如果u有子节点,u+1一定是它的另一个子节点,而另一个节点却不一定是u+2(自己可以画个图,样例就是这样的),这里只能对整个树进行编号(DFS序),然后搞DFS序

4.各种转移情况看代码

【代码】

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=1e6+50,INF=0x3f3f3f3f;
int n,m,f[maxn][4],tot=1,d[maxn][4],b[maxn],ans=1;
char str[maxn];
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;ch=getchar();
}
while(ch>='0'&&ch<='9')s=s*10+ch-'0',ch=getchar();
return s*w;
}//绿 红 蓝
// 0 1 2
void DFS(int u){
if(str[u]=='0'){
f[u][0]=d[u][0]=1;
return;
}
DFS(++tot);//递归一个子节点的
if(str[u]=='1'){//只有一个节点
f[u][0]=max(f[u+1][1],f[u+1][2])+1;//u被染绿了,那它的子节点一定不是绿色
f[u][1]=max(f[u+1][0],f[u+1][2]);//u被染红了,它的子节点一定不是红色
f[u][2]=max(f[u+1][1],f[u+1][0]);//以下同理
d[u][0]=min(d[u+1][1],d[u+1][2])+1;
d[u][1]=min(d[u+1][0],d[u+1][2]);
d[u][2]=min(d[u+1][1],d[u+1][0]);
}else if(str[u]=='2'){
int k=++tot;//这里由于建树的问题,如果u有子节点,那u+1一定是它的一个子节点,另一个节点就是k
DFS(k);//还有一个节点就递归那个节点
f[u][0]=max(f[u+1][1]+f[k][2],f[k][1]+f[u+1][2])+1;//u被染绿了,那它的两个子节点一定不是绿色,取红蓝和蓝红中最大的一个
f[u][1]=max(f[u+1][0]+f[k][2],f[k][0]+f[u+1][2]);//u被染红了,那它的两个子节点一定不是红色,取绿蓝和蓝绿中最大的一个
f[u][2]=max(f[u+1][1]+f[k][0],f[k][1]+f[u+1][0]);//以下同理
d[u][0]=min(d[u+1][1]+d[k][2],d[k][1]+d[u+1][2])+1;
d[u][1]=min(d[u+1][0]+d[k][2],d[k][0]+d[u+1][2]);
d[u][2]=min(d[u+1][1]+d[k][0],d[k][1]+d[u+1][0]);
}
ans=max(ans,f[u][0]);
return;
}
int main(){
freopen("a.in","r",stdin);
cin>>str+1;
DFS(1);
cout<<ans<<" "<<min(min(d[1][1],d[1][2]),d[1][0]);
}

【树形DP】洛谷P2585 [ZJOI2006] 三色二叉树的更多相关文章

  1. 洛谷P2585 [ZJOI2006]三色二叉树(树形dp)

    传送门 设$dp[u][i]$表示点$u$颜色为$i$时最多(最少)的绿点个数(这里用$0$表示绿点) 然后直接用树形dp就可以了 记得把情况讨论清楚 //minamoto #include<b ...

  2. 洛谷P2585 [ZJOI2006]三色二叉树

    题目描述 输入输出格式 输入格式: 输入文件名:TRO.IN 输入文件仅有一行,不超过10000个字符,表示一个二叉树序列. 输出格式: 输出文件名:TRO.OUT 输出文件也只有一行,包含两个数,依 ...

  3. 洛谷 2585 [ZJOI2006]三色二叉树——树形dp

    题目:https://www.luogu.org/problemnew/show/P2585 可以把不是绿色的记成一种.仔细一想不会有冲突.如果自己是绿色,孩子的不同颜色不会冲突:如果自己不是绿色,自 ...

  4. 【洛谷P2585】三色二叉树

    题目大意:给定一个二叉树,可以染红绿黄三种颜色,要求父节点和子节点的颜色不同,且如果一个节点有两个子节点,那么两个子节点之间的颜色也不同.求最多和最少有多少个节点会被染成绿色. 题解:加深了对二叉树的 ...

  5. luogu P2585 [ZJOI2006]三色二叉树

    P2585 [ZJOI2006]三色二叉树 题目描述 输入输出格式 输入格式: 输入文件名:TRO.IN 输入文件仅有一行,不超过10000个字符,表示一个二叉树序列. 输出格式: 输出文件名:TRO ...

  6. P2585 [ZJOI2006]三色二叉树

    题目描述 输入输出格式 输入格式: 输入文件名:TRO.IN 输入文件仅有一行,不超过500000个字符,表示一个二叉树序列. 输出格式: 输出文件名:TRO.OUT 输出文件也只有一行,包含两个数, ...

  7. 【BZOJ1864】[Zjoi2006]三色二叉树 树形DP

    1864: [Zjoi2006]三色二叉树 Description Input 仅有一行,不超过500000个字符,表示一个二叉树序列. Output 输出文件也只有一行,包含两个数,依次表示最多和最 ...

  8. BZOJ_1864_[Zjoi2006]三色二叉树_树形DP

    BZOJ_1864_[Zjoi2006]三色二叉树_树形DP 题意: 分析:递归建树,然后DP,从子节点转移. 注意到红色和蓝色没有区别,因为我们可以将红蓝互换而方案是相同的.这样的话我们只需要知道当 ...

  9. BZOJ1864[ZJOI2006]三色二叉树[树形DP]

    1864: [Zjoi2006]三色二叉树 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 773  Solved: 548[Submit][Status] ...

随机推荐

  1. Linux目录处理命令mkdir详解

    mkdir(英文原意:make directories),基本作用是创建新的目录,命令的路径及权限: 可以看到,这个命令的路径是/usr/bin/mkdir,所以它的执行权限是所有用户 mkdir 创 ...

  2. jmeter 性能测试入门手册分享

    深思熟虑之下,决定把这份性能测试入门手册分享给大家 最初整理这份教程的是因为自己在学习性能测试的过程中踩过了很多的坑,遇到了 数不清的问题,于是就想着将这些解决的问题全都归拢在一个文档里,方便自己查阅 ...

  3. git提交代码托管平台流程

    首先先安装git git官网 ---- https://git-scm.com/ 下载好傻瓜式安装即可 安装好过后,再桌面任意空白区域右键,看到以下两个选项即为安装成功 一般都用第二个选项也就是 Gi ...

  4. Docker+Selenium+TestNG+Maven+Jenkins环境搭建

    一.Selenium环境准备 standalone-chrome Docker容器启动: docker pull selenium/standalone-chrome version: '3' ser ...

  5. Jupyter的搭建

    在家实在无聊,伏案沉思良久,忽然灵机一动,何不写写Python?然而电脑上的软件早已人是物非,Pycharm已然不复存在.但是又不想装软件找激活码,于是,只好建个Jupyter先凑合一下. 1. 安装 ...

  6. [LOJ6569] 仙人掌计数

    Statement 带标号仙人掌计数问题. \(n< 131072\). Solution 设\(x\)个点的仙人掌个数的生成函数为\(C(x)\) 对于与根相邻的块, 还是仙人掌, 生成函数为 ...

  7. 数列计算I(整理四舍五入)

    问题 C: 数列计算I(点击) 时间限制: 1 Sec  内存限制: 128 MB                                                           ...

  8. 2019-02-02 Python学习之死锁和Rlock

    死锁:"当一个线程永远地持有一个锁,并且其他线程都尝试去获得这个锁时,那么它们将永远被阻塞" e.g. import threading import time mutexboy ...

  9. WebDriverWait与expected_conditions结合使用

    expected_conditions判断页面元素 demo2 from selenium import webdriver from selenium.webdriver.support.ui im ...

  10. MAC App破解之路十 Particle Design

    这个软件破解非常简单: 修改: [PaddleStatic Yz6nrtNwF4].直接返回1 效果: