ZJOI2016 三色二叉树

Posted bhllx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZJOI2016 三色二叉树相关的知识,希望对你有一定的参考价值。

首先 此题给出的时一个可以代表二叉树的一个序列

直接递归把树建出来就好了。

然后考虑DP。

比较容易想到的是一个f[i][3]的DP,分别代表以i为根时,i染三种颜色的最大数目。

直接根据限制转移即可,但代码比较长。

考虑(代码)简单一点的,

实际上,由于我们只在意绿色的染了多少,所以染其他两种色没有区别(也就是可以完全互相转换)。

所以考虑是否可以设f[i][2],分别代表以i为根时,i染或不染绿色的最大数目。

同样直接根据限制转移。

#include <bits/stdc++.h>
#define LL long long
using namespace std;

const int MAXN=5e5+10;
char Tr[MAXN];
int Id,Cnt,tot,head[MAXN],Son[MAXN][3],Min[MAXN][2],Max[MAXN][2];

void Build (int Nx) {
    Son[Nx][0]=Tr[++Cnt]-0;
    if (!Son[Nx][0]) return;
    for (int i=1;i<=Son[Nx][0];++i) {
        Son[Nx][i]=++Id;
        Build (Id);
    }
}

void Tr_DP (int Nx) {
    for (int i=1;i<=Son[Nx][0];++i) Tr_DP (Son[Nx][i]);
    if (Son[Nx][0]==0) {
        Min[Nx][1]=Max[Nx][1]=1;
        return;
    }
    else 
        if (Son[Nx][0]==1) {
            int Nex=Son[Nx][1];
            Min[Nx][1]+=Min[Nex][0]+1;
            Max[Nx][1]+=Max[Nex][0]+1;
            Min[Nx][0]=min (Min[Nex][0], Min[Nex][1]);
            Max[Nx][0]=max (Max[Nex][0], Max[Nex][1]);
        }    
        else {
            int Nex1=Son[Nx][1], Nex2=Son[Nx][2];
            Min[Nx][1]+=Min[Nex1][0]+Min[Nex2][0]+1;
            Max[Nx][1]+=Max[Nex1][0]+Max[Nex2][0]+1;
            Min[Nx][0]=min (Min[Nex1][0]+Min[Nex2][1], Min[Nex1][1]+Min[Nex2][0]);
            Max[Nx][0]=max (Max[Nex1][0]+Max[Nex2][1], Max[Nex1][1]+Max[Nex2][0]);            
        }
}

int main ()
{
    scanf ("%s", Tr+1);
    Build (++Id);
    Tr_DP (1);
    printf ("%d %d
", max (Max[1][0], Max[1][1]), min (Min[1][0], Min[1][1]) );
    return 0;
}

 

以上是关于ZJOI2016 三色二叉树的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1864: [Zjoi2006]三色二叉树(树形DP)

P2585 [ZJOI2006]三色二叉树

BZOJ_1864_[Zjoi2006]三色二叉树_树形DP

BZOJ1864[ZJOI2006]三色二叉树[树形DP]

ZJOI2006 三色二叉树

BZOJ-1864: [Zjoi2006]三色二叉树 (julao都说简单的树形DP)