Bzoj-1864

Posted zincsabian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bzoj-1864相关的知识,希望对你有一定的参考价值。

Description

技术分享图片

Input

仅有一行,不超过500000个字符,表示一个二叉树序列。

Output

输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色。

Sample Input

1122002010

Sample Output

5 2
 

题意:给定一颗有根树,可以选择染成绿色或者染成其他颜色,父亲节点相同的节点要求颜色不同,求最后最多/少有几个绿色节点

可以发现这个蓝色和红色没有用,开个数组记录一下是否染成绿色就好了,方程也很好推啊T T,第一次写树形dp也技术分享图片

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
#define ll long long
#define inf 0x7fffffff
inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
    while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
    return x*f;
}
int cnt,l[500000],r[500000];
void get(int x)
{
	char ch=getchar();
	if(ch==‘0‘) return;
	cnt++;l[x]=cnt;get(l[x]);
	if(ch==‘2‘){cnt++;r[x]=cnt;get(r[x]);}
}
int f[500000][2];
void dp(int x)
{
	if(!x) return;
	dp(l[x]);dp(r[x]);
	f[x][1]=f[l[x]][0]+f[r[x]][0]+1;
	f[x][0]=max(f[l[x]][1]+f[r[x]][0],f[l[x]][0]+f[r[x]][1]);
}
void dp2(int x)
{
	if(!x) return;
	dp2(l[x]);dp2(r[x]);
	f[x][1]=f[l[x]][0]+f[r[x]][0]+1;
	f[x][0]=min(f[l[x]][1]+f[r[x]][0],f[l[x]][0]+f[r[x]][1]);
}
int ans1,ans2;
int main()
{
	cnt=1;get(1);
	dp(1);ans1=max(f[1][1],f[1][0]);
	memset(f,0,sizeof(f));
	dp2(1);ans2=min(f[1][1],f[1][0]);
	printf("%d %d\\n",ans1,ans2);
}

 

以上是关于Bzoj-1864的主要内容,如果未能解决你的问题,请参考以下文章

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

Bzoj-1864

bzoj1864 三色二叉树

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

题解 bzoj1864: [Zjoi2006]三色二叉树 (动态规划)

BZOJ-1864: [Zjoi2006]三色二叉树 (julao都说简单的树形DP)