Tree dp
Title effect: given a binary tree nodes dyed red, green, and blue colors, seeking the maximum and minimum number of green node.
This problem achievements very sick and need some tips:
Enter the number of columns and observation problems surface, you can know that any node of the left subtree some on the left and right sub-tree, and next to the right subtree
Such a DFS may run, first left subtree search, recording the number of nodes LN left subtree, the number of array subscript ln + 1 is the root of the right subtree, then search the right sub-tree, the number of records rn node , then ln + rn + 1 is the next point to search
For staining, each node can be divided into two types: green dye and not dyed green
We can make f [i] [0/1] i represents the node subtree rooted, when i is not dyed green / green dye, the maximum number of nodes green, ff [i] [0/1] Similarly, minimum
When the time has a son i, f [i] [1] = f [ls [i]] [0] +1
When the two sons i, f [i] [0] = max (f [ls [i]] [0] + f [rs [i]] [1], f [rs [i]] [0 ] + f [ls [i]] [1]) f [i] [1] = f [ls [i]] [0] + f [rs [i]] [0] +1
For the minimum Similarly
Code:
#include<bits/stdc++.h> using namespace std; char c[1000005]; int p[1000005]; int n; int lst; int s[1000005]; int f[1000005][2]; int ff[1000005][2]; int ls[1000005],rs[1000005]; int build(int cur) { if(p[cur]==0) return 1; else if(p[cur]==1) { ls[cur]=cur+1; int t=build(cur+1); return t+1; } else { ls[cur]=cur+1; int t=build(cur+1); rs[cur]=cur+t+1; int tt=build(cur+t+1); return t+tt+1; } } void dfs(int i) { if(ls[i]!=0) dfs(ls[i]); if(rs[i]!=0) dfs(rs[i]); if(s[i]==1) { f[i][1]=f[ls[i]][0]+1; ff[i][1]=ff[ls[i]][0]+1; f[i][0]=max(f[ls[i]][0],f[ls[i]][1]); ff[i][0]=min(ff[ls[i]][0],ff[ls[i]][1]); } if(s[i]==2) { f[i][1]=f[ls[i]][0]+f[rs[i]][0]+1; ff[i][1]=ff[ls[i]][0]+ff[rs[i]][0]+1; f[i][0]=max(f[ls[i]][0]+f[rs[i]][1],f[rs[i]][0]+f[ls[i]][1]); ff[i][0]=min(ff[ls[i]][0]+ff[rs[i]][1],ff[rs[i]][0]+ff[ls[i]][1]); } } int main() { cin>>(c+1); n=strlen(c+1); for(int i=1;i<=n;i++) p[i]=c[i]-'0'; build(1); for(int i=1;i<=n;i++) { if(ls[i]&&rs[i]) s[i]=2; else if(!ls[i]&&!rs[i]) s[i]=0; else s[i]=1; if(s[i]==0) f[i][1]=ff[i][1]=1; } dfs(1); //for(int i=1;i<=n;i++) cout<<i<<' '<<f[i][0]<<' '<<f[i][1]<<endl; cout<<max(f[1][0],f[1][1])<<' '<<min(ff[1][1],ff[1][0])<<endl; return 0; }
Google Input Method ™ really hard to use