zoukankan      html  css  js  c++  java
  • BZOJ_1864_[Zjoi2006]三色二叉树_树形DP

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

    题意:

    分析:递归建树,然后DP,从子节点转移。

    注意到红色和蓝色没有区别,因为我们可以将红蓝互换而方案是相同的。这样的话我们只需要知道当前节点是否为绿色即可。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 500050
    int lson[N],rson[N],cnt,n;
    int f[N][2],g[N][2],h[N][2];
    void build(int x)
    {
        char s=getchar();
        if(s=='0')return ;
        lson[x]=++cnt;build(lson[x]);
        if(s=='2')
        {
            rson[x]=++cnt;build(rson[x]);    
        }
    }
    void dfs(int x)
    {
        int u=lson[x],v=rson[x];
        if(u==0&&v==0)
        {
            f[x][0]=f[x][1]=1;
            return ;
        }
        dfs(u);    
        if(v)
        {
            dfs(v);    
            f[x][0]=max(g[u][0]+h[v][0],g[v][0]+h[u][0])+1;
            g[x][0]=max(f[u][0]+h[v][0],f[v][0]+h[u][0]);
            h[x][0]=max(f[u][0]+g[v][0],f[v][0]+g[u][0]);
            f[x][1]=min(g[u][1]+h[v][1],g[v][1]+h[u][1])+1;
            g[x][1]=min(f[u][1]+h[v][1],f[v][1]+h[u][1]);
            h[x][1]=min(f[u][1]+g[v][1],f[v][1]+g[u][1]);
        }
        else
        {
            f[x][0]=max(g[u][0],h[u][0])+1;
            h[x][0]=max(f[u][0],g[u][0]);
            g[x][0]=max(f[u][0],h[u][0]);
            f[x][1]=min(g[u][1],h[u][1])+1;
            h[x][1]=min(f[u][1],g[u][1]);
            g[x][1]=min(f[u][1],h[u][1]);        
        }
    }
    int main()
    {
        cnt=1;
        build(1);
        dfs(1); 
        printf("%d %d",max(max(f[1][0],g[1][0]),h[1][0]),min(min(f[1][1],g[1][1]),h[1][1]));
    }
    
  • 相关阅读:
    中英切换
    vue-cli3 关闭一直运行的 /sockjs-node/info?t= ...
    vue 深拷贝
    C++ 中 typename
    将博客搬至CSDN
    死锁及处理
    C 运算符优先级
    阻塞与非阻塞,同步与异步
    同步函数与异步函数
    C 结构体位域
  • 原文地址:https://www.cnblogs.com/suika/p/8432461.html
Copyright © 2011-2022 走看看