设$dp[u][i]$表示点$u$颜色为$i$时最多(最少)的绿点个数(这里用$0$表示绿点)
然后直接用树形dp就可以了
记得把情况讨论清楚
1 //minamoto 2 #include<bits/stdc++.h> 3 #define inf 0x3f3f3f3f 4 using namespace std; 5 template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;} 6 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;} 7 const int N=5e5+5; 8 char s[N];int n,cnt,L[N],R[N],dp[N][3]; 9 void dfs(int u){ 10 ++cnt; 11 switch(s[u]){ 12 case 0:break; 13 case 1:L[u]=cnt,dfs(cnt);break; 14 case 2:L[u]=cnt,dfs(cnt),R[u]=cnt,dfs(cnt);break; 15 } 16 } 17 #define ls L[u] 18 #define rs R[u] 19 void dfsmax(int u){ 20 if(!ls) return (void)(dp[u][0]=1,dp[u][1]=dp[u][2]=0); 21 dfsmax(ls); 22 if(rs) dfsmax(rs); 23 dp[u][0]=dp[u][1]=dp[u][2]=0; 24 if(rs){ 25 cmax(dp[u][0],dp[ls][1]+dp[rs][2]+1), 26 cmax(dp[u][0],dp[ls][2]+dp[rs][1]+1); 27 28 cmax(dp[u][1],dp[ls][0]+dp[rs][2]), 29 cmax(dp[u][1],dp[ls][2]+dp[rs][0]); 30 31 cmax(dp[u][2],dp[ls][0]+dp[rs][1]), 32 cmax(dp[u][2],dp[ls][1]+dp[rs][0]); 33 }else{ 34 cmax(dp[u][0],dp[ls][1]+1),cmax(dp[u][0],dp[ls][2]+1); 35 cmax(dp[u][1],dp[ls][0]),cmax(dp[u][1],dp[ls][2]); 36 cmax(dp[u][2],dp[ls][0]),cmax(dp[u][2],dp[ls][1]); 37 } 38 } 39 void dfsmin(int u){ 40 if(!ls) return (void)(dp[u][0]=1,dp[u][1]=dp[u][2]=0); 41 dfsmin(ls); 42 if(rs) dfsmin(rs); 43 dp[u][0]=dp[u][1]=dp[u][2]=inf; 44 if(rs){ 45 cmin(dp[u][0],dp[ls][1]+dp[rs][2]+1), 46 cmin(dp[u][0],dp[ls][2]+dp[rs][1]+1); 47 48 cmin(dp[u][1],dp[ls][0]+dp[rs][2]), 49 cmin(dp[u][1],dp[ls][2]+dp[rs][0]); 50 51 cmin(dp[u][2],dp[ls][0]+dp[rs][1]), 52 cmin(dp[u][2],dp[ls][1]+dp[rs][0]); 53 }else{ 54 cmin(dp[u][0],dp[ls][1]+1),cmin(dp[u][0],dp[ls][2]+1); 55 cmin(dp[u][1],dp[ls][0]),cmin(dp[u][1],dp[ls][2]); 56 cmin(dp[u][2],dp[ls][0]),cmin(dp[u][2],dp[ls][1]); 57 } 58 } 59 int main(){ 60 // freopen("testdata.in","r",stdin); 61 scanf("%s",s+1),n=strlen(s+1); 62 for(int i=1;i<=n;++i) s[i]-='0'; 63 cnt=1,dfs(1); 64 dfsmax(1),printf("%d ",max(dp[1][0],max(dp[1][1],dp[1][2]))); 65 dfsmin(1),printf("%d ",min(dp[1][0],min(dp[1][1],dp[1][2]))); 66 return 0; 67 }