洛谷P2585 [ZJOI2006]三色二叉树
题目描述
输入输出格式
输入格式:
输入文件名:TRO.IN
输入文件仅有一行,不超过10000个字符,表示一个二叉树序列。
输出格式:
输出文件名:TRO.OUT
输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色。
输入输出样例
1122002010
5 2 似乎已经很久没有写博客了
今天是noip2017初赛,离noip2017复赛还有不到一个月,我要加油做题了! 题解:
首先得能通过输入的一串树把树的形态搞出来。自己模拟模拟后发现这个“二叉树序列”跟dfs差不多,用一个dfs就知道树是什么样的了。
在dfs时记录该节点有几个子节点(只可能是0、1、2),顺便记下子节点的编号。
之后计算最多最少几个节点被染成绿色就可以用dp了
至于问什么会想到dp呢?我猜是一个经验问题吧。
一开始想起来虽觉得不好算,但大问题可以转化为子问题后解决。对于每一个小部分求出最值后进一步求出稍大一部分的最值。
由于要求最大值与最小值,所以我用了两个dp数组。
dp[i][k]表示第i号节点的颜色为k,它与它子树中颜色为绿的的最大值。(在前面的dfs中根据dfs序可知每一个子树中的节点编号连续,且根节点是最小的)
转移方程有些长,直接看下面代码吧,懒得再写一遍了。
方程基本就是对于该节点的一种状态求出子节点可能的不同状态(状态数并不多)中的最值。
之后就可以啦 总结一下思路:
弄清楚“二叉树序列”的本质 -> 发现大问题难以求解,但可通过子问题计算出 -> 进行dp 注意:题目很坑,数据范围是有问题的,最多可能输入长度为500000 代码:
#include<cstdio>
#include<iostream>
using namespace std; const int MAXN=;
int sonnum[MAXN],son[MAXN][];
int num=,root; char ch;
void input(int u){
sonnum[u]=ch-'';
if(ch-''==) return;
else if(ch-''==){
son[u][]=++num;
ch=getchar();
input(num);
}
else{
son[u][]=++num;
ch=getchar();
input(num);
son[u][]=++num;
fa[num]=u;
ch=getchar();
input(num);
}
}
int dp[MAXN][],dp2[MAXN][]; int main()
{
int i,j,x;
ch=getchar();
while(ch<'' || ch>'') ch=getchar(); root=++num;
input(root); for(i=num;i>;i--){
if(sonnum[i]==){
dp[i][]=;
dp[i][]=dp[i][]=; dp2[i][]=;
dp2[i][]=dp2[i][]=;
}
else if(sonnum[i]==){
dp[i][]=max(dp[son[i][]][],dp[son[i][]][])+;
dp[i][]=max(dp[son[i][]][],dp[son[i][]][]);
dp[i][]=max(dp[son[i][]][],dp[son[i][]][]); dp2[i][]=min(dp2[son[i][]][],dp2[son[i][]][])+;
dp2[i][]=min(dp2[son[i][]][],dp2[son[i][]][]);
dp2[i][]=min(dp2[son[i][]][],dp2[son[i][]][]);
}
else {
dp[i][]=max(dp[son[i][]][]+dp[son[i][]][],dp[son[i][]][]+dp[son[i][]][])+;
dp[i][]=max(dp[son[i][]][]+dp[son[i][]][],dp[son[i][]][]+dp[son[i][]][]);
dp[i][]=max(dp[son[i][]][]+dp[son[i][]][],dp[son[i][]][]+dp[son[i][]][]); dp2[i][]=min(dp2[son[i][]][]+dp2[son[i][]][],dp2[son[i][]][]+dp2[son[i][]][])+;
dp2[i][]=min(dp2[son[i][]][]+dp2[son[i][]][],dp2[son[i][]][]+dp2[son[i][]][]);
dp2[i][]=min(dp2[son[i][]][]+dp2[son[i][]][],dp2[son[i][]][]+dp2[son[i][]][]);
}
}
printf("%d ",max(dp[][],max(dp[][],dp[][])));
printf("%d\n",min(dp2[][],min(dp2[][],dp2[][])));
return ;
}
洛谷P2585 [ZJOI2006]三色二叉树的更多相关文章
- 【树形DP】洛谷P2585 [ZJOI2006] 三色二叉树
[树形DP]三色二叉树 标签(空格分隔): 树形DP [题目] 一棵二叉树可以按照如下规则表示成一个由0.1.2组成的字符序列,我们称之为"二叉树序列S": 0 该树没有子节点 1 ...
- 洛谷P2585 [ZJOI2006]三色二叉树(树形dp)
传送门 设$dp[u][i]$表示点$u$颜色为$i$时最多(最少)的绿点个数(这里用$0$表示绿点) 然后直接用树形dp就可以了 记得把情况讨论清楚 //minamoto #include<b ...
- 【洛谷P2585】三色二叉树
题目大意:给定一个二叉树,可以染红绿黄三种颜色,要求父节点和子节点的颜色不同,且如果一个节点有两个子节点,那么两个子节点之间的颜色也不同.求最多和最少有多少个节点会被染成绿色. 题解:加深了对二叉树的 ...
- 洛谷 2585 [ZJOI2006]三色二叉树——树形dp
题目:https://www.luogu.org/problemnew/show/P2585 可以把不是绿色的记成一种.仔细一想不会有冲突.如果自己是绿色,孩子的不同颜色不会冲突:如果自己不是绿色,自 ...
- luogu P2585 [ZJOI2006]三色二叉树
P2585 [ZJOI2006]三色二叉树 题目描述 输入输出格式 输入格式: 输入文件名:TRO.IN 输入文件仅有一行,不超过10000个字符,表示一个二叉树序列. 输出格式: 输出文件名:TRO ...
- P2585 [ZJOI2006]三色二叉树
题目描述 输入输出格式 输入格式: 输入文件名:TRO.IN 输入文件仅有一行,不超过500000个字符,表示一个二叉树序列. 输出格式: 输出文件名:TRO.OUT 输出文件也只有一行,包含两个数, ...
- BZOJ1864[ZJOI2006]三色二叉树[树形DP]
1864: [Zjoi2006]三色二叉树 Time Limit: 1 Sec Memory Limit: 64 MBSubmit: 773 Solved: 548[Submit][Status] ...
- 【BZOJ1864】[Zjoi2006]三色二叉树 树形DP
1864: [Zjoi2006]三色二叉树 Description Input 仅有一行,不超过500000个字符,表示一个二叉树序列. Output 输出文件也只有一行,包含两个数,依次表示最多和最 ...
- BZOJ 1864: [Zjoi2006]三色二叉树( 树形dp )
难得的ZJOI水题...DFS一遍就行了... ----------------------------------------------------------------------- #inc ...
随机推荐
- H3C端口角色的确定
- keep-alive及路由渲染
切换路由的时候,每次切换的时候得重新渲染一遍,这样的话会影响到性能的.此时用<keep-alive>包裹着app里的<router-view>,进行缓存. 如果一个页面涉及到了 ...
- msbuild 项目文件常用判断条件
在写项目文件的时候,需要根据不同的条件定义或执行不同的代码,有一些比较常使用的判断,本文收藏起来,方便大家找 在 msbuild 的项目文件 cspoj 或 xx.target 等文件里面,可以使用 ...
- spring boot 实践总结(转)
pring Boot是最流行的用于开发微服务的Java框架.在本文主要分享的是在专业开发中使用Spring Boot所采用的最佳实践.这些内容是基于个人经验和一些熟知的Spring Boot专家的文章 ...
- acwing 102 -利用二分枚举区间平均值
我真的是服了,看了一晚上发现居然,,,,, 上图吧,话说有人评论没... 对于结果来说,不一定要枚举有序数列,感觉这是一种猜结果的方法,只不过特别精确,令人发指 #include<cstdio& ...
- sleep()与wait()区别
1.所在类不一样:sleep在Thread类里面,wait在Object里面. 2.sleep需要抓异常,wait则不用. 3.sleep没有释放锁,wait释放锁. 4.sleep设置了释放时间,w ...
- CCNA 学习记录(三)通过仿真理解ARP协议
拓扑图 配置 路由器R2: GigabitEthernet 0/0/0 IP Address: 192.168.1.1 Subnet Mask: 255.255.255.0 Serial 0/1/0 ...
- Git是什么?
Git是什么? Git 是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目. Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控 ...
- $[NOIp2017]$ 宝藏 状压$dp$
\(Sol\) 觉得这里是个很巧妙的地方吖,就是记下当前扩展点集的最大深度,然后强制下一步扩展的点集都是最大深度+1.这样做在当前看可能会导致误算答案导致答案偏大,但是整个\(dp\)完成后一定可以得 ...
- JVM探秘:四种引用、对象的生存与死亡
本系列笔记主要基于<深入理解Java虚拟机:JVM高级特性与最佳实践 第2版>,是这本书的读书笔记. Java虚拟机的内存区域中,程序计数器.Java栈和本地方法栈是线程私有的,随线程而生 ...