BZOJ 1864 三色二叉树

Posted on 2016-10-31 14:13  ziliuziliu  阅读(112)  评论(0编辑  收藏  举报

分颜色dp一下就行了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxv 500500
#define maxe 1000050
#define inf 2000000000
using namespace std;
char s[maxv];
int n,f[maxv][4][3],now=1,ls[maxv],rs[maxv];
void dfs1(int x)
{
    now=x;
    if (s[x-1]=='0') return;
    ls[x]=now+1;dfs1(x+1);
    if (s[x-1]=='2') {rs[x]=now+1;dfs1(now+1);}
}
void dfs2(int x)
{
    if (ls[x]) dfs2(ls[x]);
    if (rs[x]) dfs2(rs[x]);
    f[x][1][1]=max(f[ls[x]][2][1]+f[rs[x]][3][1],f[ls[x]][3][1]+f[rs[x]][2][1])+1;
    f[x][1][2]=min(f[ls[x]][2][2]+f[rs[x]][3][2],f[ls[x]][3][2]+f[rs[x]][2][2])+1;
    f[x][2][1]=max(f[ls[x]][1][1]+f[rs[x]][3][1],f[ls[x]][3][1]+f[rs[x]][1][1]);
    f[x][2][2]=min(f[ls[x]][1][2]+f[rs[x]][3][2],f[ls[x]][3][2]+f[rs[x]][1][2]);
    f[x][3][1]=max(f[ls[x]][1][1]+f[rs[x]][2][1],f[ls[x]][2][1]+f[rs[x]][1][1]);
    f[x][3][2]=min(f[ls[x]][1][2]+f[rs[x]][2][2],f[ls[x]][2][2]+f[rs[x]][1][2]);
}
void build()
{
    n=strlen(s);
    dfs1(1);
}
int main()
{
    scanf("%s",s);
    build();    
    dfs2(1);
    int ans1=0,ans2=inf;
    for (int i=1;i<=3;i++)
    {
        ans1=max(ans1,f[1][i][1]);
        ans2=min(ans2,f[1][i][2]);
    }
    printf("%d %d\n",ans1,ans2);
    return 0;
}