zoukankan      html  css  js  c++  java
  • 洛谷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
    ",min(dp[1][0],min(dp[1][1],dp[1][2])));
    66     return 0;
    67 }
  • 相关阅读:
    Some interesting problems in Group theory
    Abstract Harmonic Analysis Lecture Notes
    郭懋正《实变函数与泛函分析》课后题答案
    江泽坚《泛函分析》第二版 参考答案
    国外著名数学杂志
    郑继明等《数值分析》习题解答
    《摩诃般若波罗蜜多心经》新译 何新 译
    炼静
    金刚经原文
    道德经全文
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/9787132.html
Copyright © 2011-2022 走看看