码迷,mamicode.com
首页 > 其他好文 > 详细

Bzoj-1864

时间:2018-01-16 18:22:19      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:data   pac   有用   memset   main   颜色   etc   pre   image   

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

标签:data   pac   有用   memset   main   颜色   etc   pre   image   

原文地址:https://www.cnblogs.com/ZincSabian/p/8296134.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!