树形dp——三色二叉树
题目描述
一棵二叉树可以按照如下规则表示成一个由0、1、2组成的字符序列,我们称之为“二叉树序列S”:
0 该树没有子节点 1S1 该树有一个子节点,S1为其二叉树序列 1S1S2 该树有两个子节点,S1,S2分别为两个二叉树的序列 例如,下图所表示的二叉树可以用二叉树序列S=21200110来表示。
你的任务是要对一棵二叉树的节点进行染色。每个节点可以被染成红色、绿色或蓝色。并且,一个节点与其子节点的颜色必须不同,如果该节点有两个子节点,那么这两个子节点的颜色也必须不相同。给定一棵二叉树的二叉树序列,请求出这棵树中最多和最少有多少个点能够被染成绿色。 
输入格式
输入文件仅有一行,不超过10000个字符,表示一个二叉树序列
输出格式
输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色。
样例
样例输入
1122002010
样例输出
5 2
题目分析
讲真第一眼看见这道题想起了刚学的排列组合emmm
- 这题看起来花里胡哨,其实搞懂题以后,还是比较暴力的
- 关键点:
- 如何建树:根据题意,子串的每一个字符都代表着分支,重点在分支为0这里,分支为0说明走到了根节点,直接返回即可
- 转移方程:每个点都可以涂三种颜色,每种颜色都试一下,加上子树的dp值,而且要分开保存,最大值最小值要分开,不同的颜色也要分开,最后统一比较即可
#include <cstdio>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn =1e4+10;
char s[maxn];
int f1[maxn][3],f2[maxn][3];//f1是最大值,f2是最小值,再多开一维数组记录所涂颜色
int dfs(int root){ //返回每个子树跑dfs的末尾元素
if(s[root] == '0'){
f1[root][0] = f2[root][0] = 1;
return root;
}
int left = dfs(root+1);
if(s[root] == '1'){//根据颜色的互异性,直接分情况讨论
f1[root][0] = max(f1[root+1][1],f1[root+1][2])+1;
f1[root][1] = max(f1[root+1][0],f1[root+1][2]);
f1[root][2] = max(f1[root+1][0],f1[root+1][1]);
f2[root][0] = min(f2[root+1][1],f2[root+1][2])+1;
f2[root][1] = min(f2[root+1][0],f2[root+1][2]);
f2[root][2] = min(f2[root+1][0],f2[root+1][1]);
return left;
}
if(s[root] == '2'){//有两个子树,还需要从左子树的末尾接着跑,找出右子树
int right = dfs(left+1);
f1[root][0] = max(f1[root+1][1]+f1[left+1][2],f1[root+1][2]+f1[left+1][1])+1;
f1[root][1] = max(f1[root+1][0]+f1[left+1][2],f1[root+1][2]+f1[left+1][0]);
f1[root][2] = max(f1[root+1][0]+f1[left+1][1],f1[root+1][1]+f1[left+1][0]);
f2[root][0] = min(f2[root+1][1]+f2[left+1][2],f2[root+1][2]+f2[left+1][1])+1;
f2[root][1] = min(f2[root+1][0]+f2[left+1][2],f2[root+1][2]+f2[left+1][0]);
f2[root][2] = min(f2[root+1][0]+f2[left+1][1],f2[root+1][1]+f2[left+1][0]);
return right;
}
}
int main(){
cin>>s;
dfs(0);
int MAX = max(f1[0][0],max(f1[0][1],f1[0][2]));//三种情况进行比较,得出最大值
int MIN = min(f2[0][0],min(f2[0][1],f2[0][2]));//得出最小值
printf("%d %d",MAX,MIN);
}
树形dp——三色二叉树的更多相关文章
- 【BZOJ-1864】三色二叉树 树形DP
1864: [Zjoi2006]三色二叉树 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 659 Solved: 469[Submit][Status] ...
- 【BZOJ1864】[Zjoi2006]三色二叉树 树形DP
1864: [Zjoi2006]三色二叉树 Description Input 仅有一行,不超过500000个字符,表示一个二叉树序列. Output 输出文件也只有一行,包含两个数,依次表示最多和最 ...
- BZOJ_1864_[Zjoi2006]三色二叉树_树形DP
BZOJ_1864_[Zjoi2006]三色二叉树_树形DP 题意: 分析:递归建树,然后DP,从子节点转移. 注意到红色和蓝色没有区别,因为我们可以将红蓝互换而方案是相同的.这样的话我们只需要知道当 ...
- 【树形DP】洛谷P2585 [ZJOI2006] 三色二叉树
[树形DP]三色二叉树 标签(空格分隔): 树形DP [题目] 一棵二叉树可以按照如下规则表示成一个由0.1.2组成的字符序列,我们称之为"二叉树序列S": 0 该树没有子节点 1 ...
- BZOJ1864[ZJOI2006]三色二叉树[树形DP]
1864: [Zjoi2006]三色二叉树 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 773 Solved: 548[Submit][Status] ...
- BZOJ 1864: [Zjoi2006]三色二叉树( 树形dp )
难得的ZJOI水题...DFS一遍就行了... ----------------------------------------------------------------------- #inc ...
- 三色二叉树——树形dp
三色二叉树 题目描述 一棵二叉树可以按照如下规则表示成一个由 \(0.1.2\) 组成的字符序列,我们称之为"二叉树序列 \(S\) ": \(0\) 该树没有子节点. \(1S_ ...
- BZOJ 1864:[Zjoi2006]三色二叉树(树DP)
三色二叉树 问题描述 输入 仅有一行,不超过500000个字符,表示一个二叉树序列. 输出 输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色. 样例输入 1122002010 ...
- luogu P2585 [ZJOI2006]三色二叉树
P2585 [ZJOI2006]三色二叉树 题目描述 输入输出格式 输入格式: 输入文件名:TRO.IN 输入文件仅有一行,不超过10000个字符,表示一个二叉树序列. 输出格式: 输出文件名:TRO ...
随机推荐
- Java实现 洛谷 P1423 小玉在游泳
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = ...
- 温故知新-Mysql的体系结构概览&sql优化步骤
文章目录 Mysql的体系结构概览 连接层 服务层 引擎层 存储层 存储引擎 存储引擎概述 存储引擎特性 伴随UITabB ...
- 第一章03-Activity的启动模式
Activity的LaunchMode Android中提供了四中Activity的启动模式 1. standard 2. singleTop 3. singleTask 4. signleInsta ...
- Netty 源码解析: Netty 的 ChannelPipeline
ChannelPipeline和Inbound.Outbound 我想很多读者应该或多或少都有 Netty 中 pipeline 的概念.前面我们说了,使用 Netty 的时候,我们通 ...
- 定时器+echarts运行时间太长导致内存溢出页面崩溃
最近做的项目需要在页面上展示echarts图表,且数据每隔10s刷新一次,然后发现时间长了以后chorme浏览器会显示页面崩溃.一开始以为是定时器的原因,试了网上的很多方法,比如把setInterva ...
- 【分区】使用 GPT 分区表分区并格式化 (非 FreeBSD 系统)
新购买的 Linux 云服务器,由于数据盘未做分区和格式化,无法使用. 注意: 数据盘中的数据在格式化后将全部被清空.请在格式化之前,确保数据盘中没有数据或已对重要数据进行备份.为避免服务发生异常,格 ...
- Divisors (求解组合数因子个数)【唯一分解定理】
Divisors 题目链接(点击) Your task in this problem is to determine the number of divisors of Cnk. Just for ...
- CSS文本相关之水平排列[4]
在正常流中,文本都是从左往右.自上而下排列显示,如果想要改变排列方向的话,可以通过CSS属性来改变. text-align属性 文本排列(text-align)可改变文本在水平上的方向,但不改变内部的 ...
- 使用python求解向量值函数的雅各比(Jacobian)矩阵
考虑一个向量值函数$R^m \rightarrow R^n$,即$\textbf{y} = f(\textbf{x})$,它的雅各比(Jacobian)矩阵定义如下. 下面记录下一段使用python求 ...