luogu 2585 [ZJOI2006]三色二叉树

 

输入格式

输入文件名:TRO.IN

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

输出格式

输出文件名:TRO.OUT

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

输入输出样例

输入 #1
1122002010
输出 #1
5 2

 分析

树形DP,父子关系已经给出了,直接按顺序搜就是

只是需要记录儿子个数以便确定编号位置

dp的部分比较简单,dp[节点][颜色] = 绿色的个数

 1 /*****************************
 2 User:Mandy.H.Y
 3 Language:c++
 4 Problem:
 5 *****************************/
 6 
 7 #include<bits/stdc++.h>
 8 #define Max(x,y) ((x) > (y) ? (x) : (y))
 9 #define Min(x,y) ((x) < (y) ? (x) : (y))
10 
11 using namespace std;
12 
13 const int maxn = 5e5 + 5;
14 
15 int n;
16 char a[maxn];
17 int mi[maxn][5];
18 int ma[maxn][5];
19 
20 template<class T>inline void read(T &x){
21     x = 0;bool flag = 0;char ch = getchar();
22     while(!isdigit(ch)) flag |= ch == '-',ch = getchar();
23     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
24     if(flag) x = -x;
25 }
26 
27 template<class T>void putch(const T x){
28     if(x > 9) putch(x / 10);
29     putchar(x % 10 | 48);
30 }
31 
32 template<class T>void put(const T x){
33     if(x < 0) putchar('-'),putch(-x);
34     else putch(x);
35 }
36 
37 void file(){
38     freopen("2585.in","r",stdin);
39     freopen("2585.out","w",stdout);
40 }
41 
42 int dfs(int u){
43     switch(a[u]){
44         case '0':{
45             mi[u][0] = 1;
46             ma[u][0] = 1;
47             return 1;
48             break;
49         }
50         case '1':{
51             int ls = dfs(u+1);
52             mi[u][0] = Min(mi[u+1][1],mi[u+1][2]) + 1;
53             mi[u][1] = Min(mi[u+1][0],mi[u+1][2]) ;
54             mi[u][2] = Min(mi[u+1][0],mi[u+1][1]) ;
55             ma[u][0] = Max(ma[u+1][1],ma[u+1][2]) + 1;
56             ma[u][1] = Max(ma[u+1][0],ma[u+1][2]) ;
57             ma[u][2] = Max(ma[u+1][0],ma[u+1][1]) ;
58             return ls + 1;
59             break;
60         }
61         default:{
62             int ls = dfs(u+1);
63             int rs = dfs(u+1+ls);
64             mi[u][0] = Min(mi[u+1][1]+mi[u+1+ls][2],mi[u+1][2]+mi[u+1+ls][1]) + 1;
65             mi[u][1] = Min(mi[u+1][0]+mi[u+1+ls][2],mi[u+1][2]+mi[u+1+ls][0]);
66             mi[u][2] = Min(mi[u+1][0]+mi[u+1+ls][1],mi[u+1][1]+mi[u+1+ls][0]);
67             ma[u][0] = Max(ma[u+1][1]+ma[u+1+ls][2],ma[u+1][2]+ma[u+1+ls][1]) + 1;
68             ma[u][1] = Max(ma[u+1][0]+ma[u+1+ls][2],ma[u+1][2]+ma[u+1+ls][0]);
69             ma[u][2] = Max(ma[u+1][0]+ma[u+1+ls][1],ma[u+1][1]+ma[u+1+ls][0]);
70             return ls+rs+1;
71             break;
72         }
73     }
74 }
75 
76 void readdata(){
77     scanf("%s",a);
78 }
79 
80 void work(){
81     dfs(0);
82     put(Max(ma[0][0],Max(ma[0][1],ma[0][2])));
83     putchar(' ');
84     put(Min(mi[0][0],Min(mi[0][1],mi[0][2])));
85 
86 }
87 
88 int main(){
89 //    file();
90     readdata();
91     work();
92     return 0;
93 }
View Code

猜你喜欢

转载自www.cnblogs.com/Mandy-H-Y/p/11497310.html