[BZOJ1864][CODEVS2462]三色二叉树
题目描述 Description |
一棵二叉树可以按照如下规则表示成一个由0、1、2组成的字符序列,我们称之为“二叉树序列S”: |-0 表示该树没有子节点 S = |-1S1 表示该树有一个子节点,S1为其子树的二叉树排列 |- 2S1S2 表示该树有连个个子节点,S1、S2为其子树的二叉树排列 你的任务是要对一棵二叉树的节点进行染色。每个节点可以被染成红色、绿色或蓝色。并且,一个节点与其子节点的颜色必须不同,如果该节点有两个子节点,那么这两个子节点的颜色也必须不相同。给定一棵二叉树的二叉树序列,请求出这棵树中最多和最少有多少个点能够被染成绿色。 |
输入描述 Input Description |
输入文件仅有一行,不超过10000个字符,表示一个二叉树序列。 |
输出描述 Output Description |
输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色。 |
样例输入 Sample Input |
1122002010 |
样例输出 Sample Output |
5 2 |
数据范围及提示 Data Size & Hint |
之前的一些废话:准备期末复习。
题解:
f(i,0)表示这个点不为绿色
0个儿子:0
1个儿子:max(f(s,1),f(s,0))
2个儿子:max(f(s1,1)+f(s2,0),f(s1,0)+f(s2,2))
f(i,1)表示这个点为绿色
0个儿子:1
一个儿子:f(s,0)+1
两个儿子:f(s1,0)+f(s2,0)+1
g(i,0)表示这个点不为绿色
0个儿子:0
1个儿子:min(g(s,1),g(s,0))
2个儿子:min(g(s1,1)+g(s2,0),g(s1,0)+g(s2,2))
f(i,1)表示这个点为绿色
0个儿子:1
一个儿子:g(s,0)+1
两个儿子:g(s1,0)+g(s2,0)+1
然后把输入转化成一颗树的话。。下面代码已经写了。
代码:
#include<iostream> #include<algorithm> #include<cstdio> #include<queue> #include<cmath> #include<cstring> using namespace std; typedef long long LL; typedef pair<int,int> PII; #define mem(a,b) memset(a,b,sizeof(a)) inline int read() {int x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f; } const int maxn=500010; char s[maxn]; int len,tot=1,f[2][maxn],g[2][maxn],l[maxn],r[maxn]; void DP(int now) {if(tot>len)return;f[1][now]=1;g[1][now]=1;if(s[now]=='0')return;if(s[now]=='1'){tot++;l[now]=tot;DP(tot);f[0][now]+=max(f[0][l[now]],f[1][l[now]]);f[1][now]+=f[0][l[now]];g[0][now]+=min(g[0][l[now]],g[1][l[now]]);g[1][now]+=g[0][l[now]];}if(s[now]=='2'){tot++;l[now]=tot;DP(tot);tot++;r[now]=tot;DP(tot);f[0][now]+=max(f[1][l[now]]+f[0][r[now]],f[0][l[now]]+f[1][r[now]]);f[1][now]+=f[0][l[now]]+f[0][r[now]];g[0][now]+=min(g[1][l[now]]+g[0][r[now]],g[0][l[now]]+g[1][r[now]]);g[1][now]+=g[0][l[now]]+g[0][r[now]];} } int main() {scanf("%s",s+1);len=strlen(s+1);DP(1);printf("%d %d\n",max(f[0][1],f[1][1]),min(g[0][1],g[0][1]));return 0; }
View Code
总结:
转载于:https://www.cnblogs.com/FYH-SSGSS/p/7090898.html
[BZOJ1864][CODEVS2462]三色二叉树相关推荐
- 【BZOJ-1864】三色二叉树 树形DP
1864: [Zjoi2006]三色二叉树 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 659 Solved: 469 [Submit][Statu ...
- 1864: [Zjoi2006]三色二叉树
1864: [Zjoi2006]三色二叉树 链接 分析: 做得最智障的一题了... 首先中间输出两个数之间没空格(换行居然也过了...), 写了dp[i][0/1/2],后来知道其实dp[i][0/1 ...
- BZOJ-1864-[Zjoi2006]三色二叉树(树形dp)
Description Input 仅有一行,不超过500000个字符,表示一个二叉树序列. Output 输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色. Sample ...
- bzoj 1864: [Zjoi2006]三色二叉树
Description solution 正解:递归+树型DP 我们首先递归建树 然后考虑树型DP,我们设绿色的节点为Y,非绿色为N 我们神奇的发现:N会形成是很多条相互独立的链 也就是说 Y 的下发 ...
- 1864. [ZJOI2006]三色二叉树【树形DP】
Description Input 仅有一行,不超过500000个字符,表示一个二叉树序列. Output 输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色. Sample ...
- 洛谷P2585 [ZJOI2006]三色二叉树
题目描述 输入输出格式 输入格式: 输入文件名:TRO.IN 输入文件仅有一行,不超过10000个字符,表示一个二叉树序列. 输出格式: 输出文件名:TRO.OUT 输出文件也只有一行,包含两个数,依 ...
- 洛谷 2585 [ZJOI2006]三色二叉树——树形dp
题目:https://www.luogu.org/problemnew/show/P2585 可以把不是绿色的记成一种.仔细一想不会有冲突.如果自己是绿色,孩子的不同颜色不会冲突:如果自己不是绿色,自 ...
- 2017.9.24 三色二叉树 思考记录
树形dp入门题,,,,枚举转移即可. 设f[i][0]表示这个点不是绿色 f[i][1]表示这个点是绿色. 由于要求是相邻和两儿子,所以枚举下面点的情况转移就可以了 码: #include<io ...
- 洛谷P2585[ZJOI2006]三色二叉树(树形DP)
思路 树形DP,首先是递归建树,然后是DP状态方程转移. 代码 #include<cstdio> #include<cstring> #include<algorithm ...
- 【格局视野】三色需求与工作层次
三色需求 人们的社会经济生活本身就是一个互相交换,价值传递的循环,但这个循环有一个核心,这个核心就是社会大众的需求,也可以称为市场需求,围绕这个需求产生了层级递进的需求关系. 第一个层次是蓝色需求 是 ...
最新文章
- android源码阅读笔记1-配置源码路径/阅读源码方法讨论
- 利用?和 ??简化界面的默认配置/自定义配置
- dbeaver无法修改表数据_为什么你用不好数据透视表,看完才知道
- python的in,is和id函数
- linux ntp时间立即同步命令_如何在 Linux 下确认 NTP 是否同步?
- vue点击弹窗自动触发点击事件的解决办法
- knockout+echarts实现图表展示
- 源码安装mysql 5.1_Linux环境下源码编译安装MySQL5.1
- 05-雷海林-mysql备份原理与在TDSQL中的实践
- [C#][DevPress]手动添加控件中的子控件或者结构
- 在actionbar中加入item的方法
- 数据组织与存储(一)
- ARCGIS Pro试用申请教程以及登录页面脚本错误解决办法
- 微信小程序中基础入门
- 华为云桌面,一站式云上数字化创作深度解读
- r -括号[ ]和双括号[[ ]]之间的差异
- html图片后边自动底部对齐,css实现图片与文字底边对齐
- mybatis反向生成实体类、dao层以及映射文件
- 思科路由器无法访问互联网怎么操作?
- lenovo L480 进入bios_梅捷主板如何在bios中设置u盘启动【详细步骤】