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 }
非做顽石不可,哪管他敬仰暗唾