【树形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. vscode的个人配置

    前言 此篇只是为了记录自己vscode的设置,防止以后配置丢失,无实际意义 { "files.autoSave": "afterDelay", "ed ...

  2. 彻底搞懂 etcd 系列文章(二):etcd 的多种安装姿势

    0 专辑概述 etcd 是云原生架构中重要的基础组件,由 CNCF 孵化托管.etcd 在微服务和 Kubernates 集群中不仅可以作为服务注册与发现,还可以作为 key-value 存储的中间件 ...

  3. iOS -App主流框架UINavigationController && UITabBarController的简单使用

     一个iOS app几乎没有由一个控制器组成,除非这个app非常简单.       当app中有多个控制器的时候,就需要对这些控制器进行管理,用1个控制器去管理其他多个控制器:       如图所示: ...

  4. 96题--不同的二叉搜索树(java、中等难度)

    题目描述:给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例如下: 分析:本题可用动态规划的方法求解. 设 dp[n] 表示以 1 ... n 为节点组成的二叉搜索树的种类 ...

  5. Postgresql DB安装和使用问题记录

    2.选择语言后提示: Error: There has been an error. Please put SELinux in permissive mode and then run instal ...

  6. (数据科学学习手札87)利用adjustText解决matplotlib文字标签遮挡问题

    本文示例代码.数据已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 在进行数据可视化时我们常常需要在可视化作品 ...

  7. LR字符串处理函数-lr_save_int

    int lr_save_int(int value,const char * param_name); value:要分配给参数的整数值.  param_name:参数的名称.  lr_save_in ...

  8. java锁总结

    1.公平锁与非公平锁 公平锁:指多个线程在等待同一个锁时,必须按照申请锁的先后顺序来依次获得锁. 优点:等待锁的线程不会饿死.缺点:整体效率相对较低. 非公平锁:可以抢占,即如果在某个时刻有线程需要获 ...

  9. RedHat服务器安装

    为什么选择 RedHat 市场占有率商业化比较高 厂商的支持比较丰富 新手建议ubuntu 进行上手 等熟悉了Linux环境可以选择自己喜欢的发行版 (有些Geeker就是认为Ubuntu太易于使用了 ...

  10. 详述@Responsebody和HTTP异步请求的关系

    Map.ModelAndView.User.List等对象都可以作为返回值.上述这两种对象都可以使用此注解.使用此注解即表示是在同一次请求的响应体里返回.浏览器以异步http的方式来接收.比如后端的M ...