P2585 [ZJOI2006] 三色二叉树

/*
一棵二叉树 用三种颜色染色 相邻必须不同 且 若有两个子节点 三点互不相同
dp[u][0/1/2] u染成0/1/2 u的子树中绿色最多有几个
f[u][0/1/2] u染成0/1/2 u的子树中绿色最少有几个
->1son
dp[u][0]=max(dp[v][1],dp[v][2])+1;
dp[u][1]=max(dp[v][0],dp[v][2]);
dp[u][2]=max(dp[v][0],dp[v][1]);

->2son
dp[u][0]=max(dp[v1][1]+dp[v2][2],)+1;
dp[u][1]=
dp[u][2]=

*/
/*
1122002010

5 2
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string.h>
#include<queue>
#include<vector>
#include<bits/stdc++.h>
#define ll long long
#define ddd printf("-----------------------\n");
using namespace std;
const int maxn=5e5 +10;
const int mod=998244353;
const int inf=0x3f3f3f3f;

char s[maxn];
int f[maxn][4],dp[maxn][4],cnt;

void dfs(int x)
{
    if(s[x]=='0'){
        dp[x][0]=f[x][0]=1;
        return;
    }
    dfs(++cnt);
    
    if(s[x]=='1')
    {
        dp[x][0]=max(dp[x+1][1],dp[x+1][2])+1;
        dp[x][1]=max(dp[x+1][0],dp[x+1][2]);
        dp[x][2]=max(dp[x+1][1],dp[x+1][0]);
        
        f[x][0]=min(f[x+1][1],f[x+1][2])+1;
        f[x][1]=min(f[x+1][0],f[x+1][2]);
        f[x][2]=min(f[x+1][1],f[x+1][0]);
    }
    else
    {
        int k=++cnt;
        dfs(k);
        dp[x][0]=max(dp[x+1][1]+dp[k][2],dp[x+1][2]+dp[k][1])+1;           
        dp[x][1]=max(dp[x+1][0]+dp[k][2],dp[x+1][2]+dp[k][0]);
        dp[x][2]=max(dp[x+1][0]+dp[k][1],dp[x+1][1]+dp[k][0]);
        
        f[x][0]=min(f[x+1][1]+f[k][2],f[x+1][2]+f[k][1])+1;           
        f[x][1]=min(f[x+1][0]+f[k][2],f[x+1][2]+f[k][0]);
        f[x][2]=min(f[x+1][0]+f[k][1],f[x+1][1]+f[k][0]);
    }
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>s+1;
    
    dfs(++cnt);
    
    cout<<max(dp[1][0],max(dp[1][1],dp[1][2]))<<" "<<min(f[1][0],min(f[1][1],f[1][2]))<<'\n'; 
    return 0;
}

 

posted @ 2023-11-08 14:54  JMXZ  阅读(13)  评论(0)    收藏  举报