洛谷P2585 [ZJOI2006]三色二叉树(树形dp)

传送门

设$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\n",min(dp[1][0],min(dp[1][1],dp[1][2])));
66     return 0;
67 }

猜你喜欢

转载自www.cnblogs.com/bztMinamoto/p/9787132.html