BZOJ_1864_[Zjoi2006]三色二叉树_树形DP
2024-10-16 01:18:13
BZOJ_1864_[Zjoi2006]三色二叉树_树形DP
题意:
分析:递归建树,然后DP,从子节点转移。
注意到红色和蓝色没有区别,因为我们可以将红蓝互换而方案是相同的。这样的话我们只需要知道当前节点是否为绿色即可。
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 500050
int lson[N],rson[N],cnt,n;
int f[N][2],g[N][2],h[N][2];
void build(int x)
{
char s=getchar();
if(s=='0')return ;
lson[x]=++cnt;build(lson[x]);
if(s=='2')
{
rson[x]=++cnt;build(rson[x]);
}
}
void dfs(int x)
{
int u=lson[x],v=rson[x];
if(u==0&&v==0)
{
f[x][0]=f[x][1]=1;
return ;
}
dfs(u);
if(v)
{
dfs(v);
f[x][0]=max(g[u][0]+h[v][0],g[v][0]+h[u][0])+1;
g[x][0]=max(f[u][0]+h[v][0],f[v][0]+h[u][0]);
h[x][0]=max(f[u][0]+g[v][0],f[v][0]+g[u][0]);
f[x][1]=min(g[u][1]+h[v][1],g[v][1]+h[u][1])+1;
g[x][1]=min(f[u][1]+h[v][1],f[v][1]+h[u][1]);
h[x][1]=min(f[u][1]+g[v][1],f[v][1]+g[u][1]);
}
else
{
f[x][0]=max(g[u][0],h[u][0])+1;
h[x][0]=max(f[u][0],g[u][0]);
g[x][0]=max(f[u][0],h[u][0]);
f[x][1]=min(g[u][1],h[u][1])+1;
h[x][1]=min(f[u][1],g[u][1]);
g[x][1]=min(f[u][1],h[u][1]);
}
}
int main()
{
cnt=1;
build(1);
dfs(1);
printf("%d %d",max(max(f[1][0],g[1][0]),h[1][0]),min(min(f[1][1],g[1][1]),h[1][1]));
}
最新文章
- maven工程使用spring-boot-devtools进行热部署,更改代码避免重启web容器
- C#函数式编程之标准高阶函数
- Xcode 文档注释方法
- Reverse Bits
- Populating Tabular Data Block Manually Using Cursor in Oracle Forms
- Eclipse can&#39;t install updates
- Mysql 8个小时连接断开问题解析
- new Date()的参数
- 微软HR泄露的asp.net面试题
- mvc4中的过滤器
- 网络编程中select模型和poll模型学习(linux)
- LeetCode(3):无重复字符的最大子串
- JVM、Gc工作机制详解
- WPF设置对象隐藏、不可用
- vue动态改变样式
- SpringBoot配置多数据源时遇到的问题
- Vue + Element UI 实现权限管理系统 前端篇(七):功能组件封装
- 如何对hashmap按value值排序
- 学习angualr之前需要了解的typeScript知识
- 1020 Tree Traversals (25)(25 point(s))