题目描述

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

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

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

题目大意:

给你一棵树,相邻点不同色,共三色,求一种颜色最多最少涂法。
分析:

根据题目条件列转移方程:

性质1.因为有三种颜色,所以如果父节点不是绿,那么两儿子必有一个是绿。(废话1)

性质2.如果父节点是绿,而两个子节点必然都不绿,且不冲突。(废话2)

我们不妨设置两种情况(新开一维度):dp[ rt ][ 0 ]表示 rt这个点不是绿色,dp[ rt ][ 1 ]表示是绿色,dp数组的值表示以这个点为根节点的树最多涂几个绿点。
我们可以给每一个节点设置初始值:dp[ rt ][ 0 ]=0,dp[ rt ][ 1 ]=1(很好理解吧。。。)

转移方程:1. dp[ rt ][ 1]=dp[ lch[ rt ] ] [ 0 ]+dp[ rch[ rt ] ] [ 0 ]+1;

      该点涂绿情况:左儿子不涂绿情况+右儿子不涂绿情况+自己;

      (如果这个点涂成绿色,那么左右两点都不可以涂成绿色,且这样的左右两点不冲突情况必定存在,即性质2)

     2.dp[ rt ][ 0 ]=min/max ( dp[ lch[ rt ] ] [ 0 ]+dp[ rch[ rt ] ] [ 1 ]  ,  dp[ lch[ rt ] ] [ 1]+dp[ rch[ rt ] ] [ 0 ] );

      该点不涂绿情况:左儿子不涂绿,右儿子涂绿或者左儿子涂绿,右儿子不涂绿。

      (也是必然条件,符合上面性质1)

然后就是dfs了

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int maxn=1e6+10;
char s[maxn];int a[maxn];
int cnt=1;//用来确定dfs序,因为1是根了,所以已经有一个了(废话) int lch[maxn],rch[maxn],dp[maxn][2];
void build(int rt){//递归建树,自行理解,代码不唯一
if(a[rt]==1){
lch[rt]=++cnt;
build(lch[rt]);
}else if(a[rt]==2){
lch[rt]=++cnt;
build(lch[rt]);
rch[rt]=++cnt;
build(rch[rt]);
}else if(a[rt]==0){
return;
}
}
void dfsmax(int rt){
dp[rt][1]=1;dp[rt][0]=0;
if(lch[rt])dfsmax(lch[rt]);
if(rch[rt])dfsmax(rch[rt]);
dp[rt][1]=1+dp[lch[rt]][0]+dp[rch[rt]][0];
dp[rt][0]=max(dp[lch[rt]][1]+dp[rch[rt]][0],dp[lch[rt]][0]+dp[rch[rt]][1]);
//转移方程
}
void dfsmin(int x){
dp[x][1]=1;dp[x][0]=0;
if(lch[x]) dfsmin(lch[x]);
if(rch[x]) dfsmin(rch[x]);
dp[x][1]=1+dp[lch[x]][0]+dp[rch[x]][0];
dp[x][0]=min(dp[lch[x]][1]+dp[rch[x]][0],dp[lch[x]][0]+dp[rch[x]][1]);
}
int main(){
scanf("%s",s);
int len=strlen(s);
for(int i=0;i<len;i++){
a[i+1]=s[i]-'0';//字符数组转整形,可忽略
}
build(1);
dfsmax(1);//以1为根节点建树并进行下列操作
printf("%d ",max(dp[1][1],dp[1][0]));//根节点里面保存的就是整个树的情况了
memset(dp,0,sizeof(dp));//记得初始化!!!
dfsmin(1);
printf("%d ",min(dp[1][1],dp[1][0]));
return 0;
}

三色二叉树 ---伪树形dp的更多相关文章

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

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

  2. 三色二叉树_树形DP

    Time Limit: 1000 mSec    Memory Limit : 32768 KB  Problem Description 一棵二叉树可以按照如下规则表示成一个由0.1.2组成的字符序 ...

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

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

  4. BZOJ-1864-[Zjoi2006]三色二叉树(树形dp)

    Description Input 仅有一行,不超过500000个字符,表示一个二叉树序列. Output 输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色. Sample ...

  5. 1864. [ZJOI2006]三色二叉树【树形DP】

    Description Input 仅有一行,不超过500000个字符,表示一个二叉树序列. Output 输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色. Sample ...

  6. BZOJ 1864:[Zjoi2006]三色二叉树(树DP)

    三色二叉树 问题描述 输入 仅有一行,不超过500000个字符,表示一个二叉树序列. 输出 输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色. 样例输入 1122002010 ...

  7. BZOJ 1864 三色二叉树 - 树型dp

    传送门 题目大意: 给一颗二叉树染色红绿蓝,父亲和儿子颜色必须不同,两个儿子颜色必须不同,问最多和最少能染多少个绿色的. 题目分析: 裸的树型dp:\(dp[u][col][type]\)表示u节点染 ...

  8. 【BZOJ-1864】三色二叉树 树形DP

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

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

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

随机推荐

  1. C#封装YOLOv4算法进行目标检测

    C#封装YOLOv4算法进行目标检测 概述 官网:https://pjreddie.com/darknet/ Darknet:[Github] C#封装代码:[Github] YOLO: 是实现实时物 ...

  2. C# 读取 ttf字体文件里的 Unicode

    因为爬虫要解析 &#x880cc这种字体编码的值,下载到一个ttf文件,用百度字体编辑器 打开,可以看到每个字符对应的Unicode (数字下方 $23.$2A...这些), 我需要拿到这些映 ...

  3. [程序员代码面试指南]字符串问题-字符串匹配问题(DP)

    问题描述 字符串str,模式串exp. 必须保证str中无'.'和'星号'字符,并且exp中'星号'不出现在首位,且无连续两个'星号'.PS星号是字符只是暂时没找到markdown的星号转义字符. ' ...

  4. 使用阿里云OSS的服务端签名后直传功能

    网站一般都会有上传功能,而对象存储服务oss是一个很好的选择.可以快速的搭建起自己的上传文件功能. 该文章以使用阿里云的OSS功能为例,记录如何在客户端使用阿里云的对象存储服务. 服务端签名后直传 背 ...

  5. 常用的CSS命名规范大总结

    转载: http://www.php.cn/toutiao-417563.html 文本命名规范 index.css: 一般用于首页建立样式 head.css: 头部样式,当多个页面头部设计风格相同时 ...

  6. dubbo负载均衡

    dubbo 一.同一个dubbo生产者服务怎么分布在不同服务器,且能进行负载均衡? 只要两个服务的id,接口,实现类一致(且dubbo:application名称一致,表示同一应用),注册到同一zoo ...

  7. hystrix源码之概述

    概述 hystrix核心原理是通过代理执行用户命令,记录命令执行的metrics信息,通过这些metrics信息进行降级和熔断. 源码结构包括一下几个部分: 熔断器 熔断器就是hystrix用来判断调 ...

  8. 【转】Locust性能-零基础入门系列(1)-wait_time属性用法

    本篇文章,从局部出发,利用一个简单的测试,来说明场景模拟的wait_time属性的用法.wait_time为什么要单独拎出来讲,是因为它主要有两种模式,而初学者对这两种模式,容易混淆.1) wait_ ...

  9. 并发编程(八)Lock锁

    一.引言 线程并发的过程中,肯定会设计到一个变量共享的概念,那么我们在多线程运行过程中,怎么保证每个先拿获取的变量信息都是最新且有序的呢?这一篇我们来专门学习一下Lock锁. 我们先来了解几个概念: ...

  10. Java Web学习(五)session、cookie、token

    文章更新时间:2020/09/14 一.引言 动态网页兴起后,会话管理变成开发者需要考虑的一个问题,由于HTTP请求是无状态的,为了区分每个用户,此时引入了会话标识(sessionId)的概念,但是存 ...