zoukankan      html  css  js  c++  java
  • 洛谷 P2585 [ ZJOI 2006 ] 三色二叉树 —— 树形DP

    题目:https://www.luogu.org/problemnew/show/P2585

    首先,三色其实记录两种状态:是绿色,不是绿色 即可,因为红蓝可以随意取反;

    一开始因为懒得还原出树,所以写了个错误贪心-_-

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int const maxn=500005;
    int k,mx,mn,siz[maxn];
    char a[maxn];
    int dfs()
    {
        k++; siz[k]=1; int tmp=k;//
        int nw=a[k]-'0';
        if(nw==0)return siz[k];
        else if(nw==1)siz[tmp]+=dfs();
        else siz[tmp]+=dfs(),siz[tmp]+=dfs();
        return siz[tmp];
    }
    void dfsmx(int col)
    {
        if(col)mx++;
        k++; int nw=a[k]-'0';
        if(nw==0)return;
        else if(nw==1)dfsmx(!col);
        else
        {
            if(siz[k+1]<siz[k]-siz[k+1])dfsmx(!col),dfsmx(0);
            else dfsmx(0),dfsmx(!col);
        }
    }
    void dfsmn(int col)
    {
        if(col)mn++;
        k++; int nw=a[k]-'0';
        if(nw==0)return;
        else if(nw==1)dfsmn(0);
        else
        {
            if(siz[k+1]>siz[k]-siz[k+1])dfsmn(!col),dfsmn(0);
            else dfsmn(0),dfsmn(!col);
        }
    }
    int main()
    {
        scanf("%s",a+1);
        k=0; dfs();
        k=0; dfsmx(1);
        k=0; dfsmn(0);
        printf("%d %d
    ",mx,mn);
        return 0;
    }

    实际上是树形DP啦,f[x][0/1] 表示 x 选非绿色或绿色的最大答案,g[x][0/1] 表示最小答案;

    然后转移即可。

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int const maxn=5e5+5;
    int n,k,ls[maxn],rs[maxn],f[maxn][2],g[maxn][2];
    char a[maxn];
    void init()
    {
        k++; int nw=a[k]-'0'; int tmp=k;
        if(nw==0)return;
        else if(nw==1)ls[tmp]=k+1,init();
        else ls[tmp]=k+1,init(),rs[tmp]=k+1,init();
    }
    void dfs(int x)
    {
        f[x][1]=1; g[x][1]=1;
        if(!ls[x])return;
        else if(!rs[x])
        {
            int u=ls[x];
            dfs(u);
            f[x][0]+=f[u][1]; f[x][1]+=f[u][0];
            g[x][0]+=g[u][0]; g[x][1]+=g[u][0];
        }
        else
        {
            int u=ls[x],v=rs[x];
            dfs(u); dfs(v);
            f[x][0]+=max(f[u][0]+f[v][1],f[u][1]+f[v][0]);
            f[x][1]+=f[u][0]+f[v][0];
            g[x][0]+=min(g[u][0]+g[v][1],g[u][1]+g[v][0]);
            g[x][1]+=g[u][0]+g[v][0];
        }
    }
    int main()
    {
        scanf("%s",a+1); 
        k=0; init();
        dfs(1);
        printf("%d %d
    ",max(f[1][0],f[1][1]),min(g[1][0],g[1][1]));
        return 0;
    }
  • 相关阅读:
    Java开发web的几种开发模式
    Tomcat7.0安装配置
    Apache与Tomcat 区别联系
    编写 Window 服务程序
    系列文章--SharePoint 开发教程
    Google Chrome浏览器调试功能介绍
    Chrome的JS调试工具
    Google Chrome 调试JS简单教程[更新]
    ASP.NET常用标准配置web.config
    WINDOWS下kill进程的命令
  • 原文地址:https://www.cnblogs.com/Zinn/p/9677841.html
Copyright © 2011-2022 走看看