原题地址:https://www.luogu.org/problemnew/show/P2585

题目大意:可以把一个节点染成三种颜色,父节点和两个子节点(可以有一个)颜色不能相同。求最多(少)能有多少个点能被染成绿色


由于是一棵树,多决策的问题,很明显的树形DP。

关于树形DP详见https://www.cnblogs.com/lizitong/p/10020914.html

二维状态,dp[i][j] j取0,1,2表示三种颜色。表示以这个编号为父节点取这个颜色时候有dp[i][j]个点能被染成绿色。

DFS搜到最底,然后给叶节点附上初值。

然后回溯更新。

以最小值为例。

dpmi[x][1] = min(dpmi[x][1],min(dpmi[l[x]][2]+dpmi[r[x]][3],dpmi[l[x]][3]+dpmi[r[x]][2])+1);
dpmi[x][2] = min(dpmi[x][2],min(dpmi[l[x]][1]+dpmi[r[x]][3],dpmi[l[x]][3]+dpmi[r[x]][1]));
dpmi[x][3] = min(dpmi[x][3],min(dpmi[l[x]][1]+dpmi[r[x]][2],dpmi[l[x]][2]+dpmi[r[x]][1]));

如果这个点是绿色,就比较子节点分别为其他两种颜色的大小,然后+1

如果这个点是其他颜色,就比较这两个点子节点分别是另外两种颜色和的大小。

最后输出父节点的最大(小)状态。

分别用l和r数组存左右儿子。

细节较多,上代码。

#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#define N 500005
using namespace std;
char c[N];
struct edge
{
int to;
int nxt;
int from;
}eg[N];
int head[N];
int cnt = ;
int ct = ;
int dpma[N][];
int dpmi[N][];
int l[N];
int r[N];
void add(int x,int y)
{
eg[cnt].to = y;
eg[cnt].nxt = head[x];
eg[cnt].from = x;
head[x] = cnt++;
}
void buildtree(int x)
{
if(c[x]=='')
{
add(x,++ct);
l[x] = ct;
buildtree(ct);
add(x,++ct);
r[x] = ct;
buildtree(ct);
}else if(c[x]=='')
{
add(x,++ct);
l[x] = ct;
buildtree(ct);
}else
{
return ;
}
}
void dfsma(int x)
{
if(l[x]==&&r[x]==)
{
dpma[x][] = ;
return ;
}else
{
if(l[x])
{
dfsma(l[x]);
dpma[x][] = max(dpma[x][],max(dpma[l[x]][]+dpma[r[x]][],dpma[l[x]][]+dpma[r[x]][])+);
dpma[x][] = max(dpma[x][],max(dpma[l[x]][]+dpma[r[x]][],dpma[l[x]][]+dpma[r[x]][]));
dpma[x][] = max(dpma[x][],max(dpma[l[x]][]+dpma[r[x]][],dpma[l[x]][]+dpma[r[x]][]));
}
if(r[x])
{
dfsma(r[x]);
dpma[x][] = max(dpma[x][],max(dpma[l[x]][]+dpma[r[x]][],dpma[l[x]][]+dpma[r[x]][])+);
dpma[x][] = max(dpma[x][],max(dpma[l[x]][]+dpma[r[x]][],dpma[l[x]][]+dpma[r[x]][]));
dpma[x][] = max(dpma[x][],max(dpma[l[x]][]+dpma[r[x]][],dpma[l[x]][]+dpma[r[x]][]));
}
}
}
void dfsmi(int x)
{
if(l[x]==&&r[x]==)
{
dpmi[x][] = ;
dpmi[x][] = ;
dpmi[x][] = ;
return ;
}else
{
if(l[x])
{
dfsmi(l[x]);
dpmi[x][] = min(dpmi[x][],min(dpmi[l[x]][]+dpmi[r[x]][],dpmi[l[x]][]+dpmi[r[x]][])+);
dpmi[x][] = min(dpmi[x][],min(dpmi[l[x]][]+dpmi[r[x]][],dpmi[l[x]][]+dpmi[r[x]][]));
dpmi[x][] = min(dpmi[x][],min(dpmi[l[x]][]+dpmi[r[x]][],dpmi[l[x]][]+dpmi[r[x]][]));
}
if(r[x])
{
dfsmi(r[x]);
dpmi[x][] = min(dpmi[x][],min(dpmi[l[x]][]+dpmi[r[x]][],dpmi[l[x]][]+dpmi[r[x]][])+);
dpmi[x][] = min(dpmi[x][],min(dpmi[l[x]][]+dpmi[r[x]][],dpmi[l[x]][]+dpmi[r[x]][]));
dpmi[x][] = min(dpmi[x][],min(dpmi[l[x]][]+dpmi[r[x]][],dpmi[l[x]][]+dpmi[r[x]][]));
}
}
}
int main()
{
scanf("%s",c+);
buildtree();
memset(dpmi,0x3f,sizeof(dpmi));
dpmi[][] = ;
dpmi[][] = ;
dpmi[][] = ;
dfsma();
dfsmi();
printf("%d ",max(max(dpma[][],dpma[][]),dpma[][]));
printf("%d",min(min(dpmi[][],dpmi[][]),dpmi[][]));
}

[Zjoi2006]三色二叉树(bzoj1864)(洛谷2585)题解的更多相关文章

  1. BZOJ1864[ZJOI2006]三色二叉树[树形DP]

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

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

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

  3. bzoj千题计划212:bzoj1864: [Zjoi2006]三色二叉树

    http://www.lydsy.com/JudgeOnline/problem.php?id=1864 #include<cstdio> #include<cstring> ...

  4. 嘴巴题5 「BZOJ1864」[ZJOI2006] 三色二叉树

    1864: [Zjoi2006]三色二叉树 Time Limit: 1 Sec Memory Limit: 64 MB Submit: 1195 Solved: 882 [Submit][Status ...

  5. BZOJ 1864: [Zjoi2006]三色二叉树( 树形dp )

    难得的ZJOI水题...DFS一遍就行了... ----------------------------------------------------------------------- #inc ...

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

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

  7. 【BZOJ】1864: [Zjoi2006]三色二叉树

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

  8. 1864: [Zjoi2006]三色二叉树

    1864: [Zjoi2006]三色二叉树 链接 分析: 做得最智障的一题了... 首先中间输出两个数之间没空格(换行居然也过了...), 写了dp[i][0/1/2],后来知道其实dp[i][0/1 ...

  9. [ZJOI2006]三色二叉树

    [ZJOI2006]三色二叉树 BZOJ luogu 分3种颜色讨论转移一下 #include<bits/stdc++.h> using namespace std; const int ...

  10. luogu P2585 [ZJOI2006]三色二叉树

    P2585 [ZJOI2006]三色二叉树 题目描述 输入输出格式 输入格式: 输入文件名:TRO.IN 输入文件仅有一行,不超过10000个字符,表示一个二叉树序列. 输出格式: 输出文件名:TRO ...

随机推荐

  1. ES7.3.0配置邮件告警

    情况说明: 三台es组成集群,一台kibana,版本均为7.3.0 es版本要求是白金版,基础版的不行,不过可以试用30天的白金版 步骤:先说我自己走通的流程,然后介绍官方说明 1.因为我这边使用的是 ...

  2. jmeter(二十七)分布式压测注意事项

    之前的博客:jemter(二十三):分布式测试简略的介绍了利用jmeter做分布式测试的方法,当时只是介绍了背景和原因,以及基本的配置操作,有同学说写得不够详细. 正好今年双十一,我司的全链路压测,也 ...

  3. c#读取appsetting.json配置文件

    asp.net core 取消了web.config配置文件,而将appsetting.json作为了配置文件. 那么,怎么读取相关数据呢?这里我在appsetting.json中添加一些信息 第一种 ...

  4. Syste.IO命名空间下的流操作类之间的关系

  5. 使用Nexus3搭建Maven私服+上传第三方jar包到本地maven仓库

    1.搭建Maven私服背景 公司还是按捺不住,要搭建一个自己的Maven本地仓库,可以让开发人员down架包,从内网还是快很多. 这样公司的maven本地仓库就是 开发人员自己电脑上的maven仓库 ...

  6. 40、js技巧(持续更新。。。)

    1.深拷贝对象: const a={name:'aaa',age:11} const b=JSON.parse(JSON.stringify(a)) 2.获取数组极值: let list = [1, ...

  7. Js编程实践

    js编程实践思维导向图 ---欢迎收藏 ^ - ^

  8. 如何实现android和服务器长连接

    转载 这种功能实际上就是数据同步,同时要考虑手机本身.电量.网络流量等等限制因素,所以通常在移动端上有一下两个解决方案: 1.一种是定时去server查询数据,通常是使用HTTP协议来访问web服务器 ...

  9. mysql修改密码策略

      版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/Hello_World_QWP/arti ...

  10. 【Netty】Netty的Hello World程序之Discard Server

    一.有关Discard Server的说明 世界上最简单的协议(程序)不是“Hello, World!”而是Discard(丢弃).它是一种丢弃任何接收到的数据而没有任何响应的协议. 要实现丢弃协议, ...