[ZJOI2006] binary tricolor

Tree dp

Topic Portal

Title effect: given a binary tree nodes dyed red, green, and blue colors, seeking the maximum and minimum number of green node.

This problem achievements very sick and need some tips:

Enter the number of columns and observation problems surface, you can know that any node of the left subtree some on the left and right sub-tree, and next to the right subtree

Such a DFS may run, first left subtree search, recording the number of nodes LN left subtree, the number of array subscript ln + 1 is the root of the right subtree, then search the right sub-tree, the number of records rn node , then ln + rn + 1 is the next point to search

 

For staining, each node can be divided into two types: green dye and not dyed green

We can make f [i] [0/1] i represents the node subtree rooted, when i is not dyed green / green dye, the maximum number of nodes green, ff [i] [0/1] Similarly, minimum

When the time has a son i, f [i] [1] = f [ls [i]] [0] +1

When the two sons i, f [i] [0] = max (f [ls [i]] [0] + f [rs [i]] [1], f [rs [i]] [0 ] + f [ls [i]] [1]) f [i] [1] = f [ls [i]] [0] + f [rs [i]] [0] +1

For the minimum Similarly

Code:

#include<bits/stdc++.h>
using namespace std;
char c[1000005];
int p[1000005];
int n;
int lst;
int s[1000005];
int f[1000005][2];
int ff[1000005][2];
int ls[1000005],rs[1000005];
int build(int cur)
{
    if(p[cur]==0) return 1;
    else if(p[cur]==1)
    {
        ls[cur]=cur+1;
        int t=build(cur+1);
        return t+1;
    }
    else
    {
        ls[cur]=cur+1;
        int t=build(cur+1);
        rs[cur]=cur+t+1;
        int tt=build(cur+t+1);
        return t+tt+1;
    }
}
void dfs(int i)
{
    if(ls[i]!=0) dfs(ls[i]);
    if(rs[i]!=0) dfs(rs[i]);
    if(s[i]==1)
    {
        f[i][1]=f[ls[i]][0]+1;
        ff[i][1]=ff[ls[i]][0]+1;
        f[i][0]=max(f[ls[i]][0],f[ls[i]][1]);
        ff[i][0]=min(ff[ls[i]][0],ff[ls[i]][1]);
    }
    if(s[i]==2)
    {
        f[i][1]=f[ls[i]][0]+f[rs[i]][0]+1;
        ff[i][1]=ff[ls[i]][0]+ff[rs[i]][0]+1;
        f[i][0]=max(f[ls[i]][0]+f[rs[i]][1],f[rs[i]][0]+f[ls[i]][1]);
        ff[i][0]=min(ff[ls[i]][0]+ff[rs[i]][1],ff[rs[i]][0]+ff[ls[i]][1]);
    }
}
int main()
{
    cin>>(c+1);
    n=strlen(c+1);
    for(int i=1;i<=n;i++) p[i]=c[i]-'0';
    build(1);
    for(int i=1;i<=n;i++)
    {
        if(ls[i]&&rs[i]) s[i]=2;
        else if(!ls[i]&&!rs[i]) s[i]=0;
        else s[i]=1;
        if(s[i]==0) f[i][1]=ff[i][1]=1;
    }
    dfs(1);
    //for(int i=1;i<=n;i++) cout<<i<<' '<<f[i][0]<<' '<<f[i][1]<<endl;
    cout<<max(f[1][0],f[1][1])<<' '<<min(ff[1][1],ff[1][0])<<endl;
    return 0;
}

Google Input Method ™ really hard to use

 

Guess you like

Origin www.cnblogs.com/ssf-xiaoban/p/11614853.html