• 【BZOJ1864】[Zjoi2006]三色二叉树 树形DP


    1864: [Zjoi2006]三色二叉树

    Description

    Input

    仅有一行,不超过500000个字符,表示一个二叉树序列。

    Output

    输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色。

    Sample Input

    1122002010

    Sample Output

    5 2

    题解:经典的树形DP题。用f[i]表示点i是绿色时最多有多少个点能被染成绿色,g[i]表示i不是绿色时最多有多少个点被染成绿色,容易推出状态转移方程:

    f[i]=g[ch[i][0]]+g[ch[i][1]]+1;

    g[i]=max(f[ch[i][0]]+g[ch[i][1]],f[ch[i][1]]+g[ch[i][0]]);

    最小值把max换成min即可。

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    using namespace std;
    const int maxn=500010;
    char str[maxn];
    int sta[maxn],top;
    int f[maxn],g[maxn],ch[maxn][2];
    int n;
    int main()
    {
        scanf("%s",str);
        n=strlen(str);
        int i,j;
        for(i=1;i<=n;i++)
        {
            if(ch[sta[top]][0])    ch[sta[top]][1]=i;
            else    ch[sta[top]][0]=i;
            top--;
            for(j=1;j<=str[i-1]-'0';j++)    sta[++top]=i;
        }
        for(i=n;i>=1;i--)
        {
            f[i]=g[ch[i][0]]+g[ch[i][1]]+1;
            g[i]=max(f[ch[i][0]]+g[ch[i][1]],f[ch[i][1]]+g[ch[i][0]]);
        }
        printf("%d ",max(f[1],g[1]));
        for(i=n;i>=1;i--)
        {
            f[i]=g[ch[i][0]]+g[ch[i][1]]+1;
            g[i]=min(f[ch[i][0]]+g[ch[i][1]],f[ch[i][1]]+g[ch[i][0]]);
        }
        printf("%d",min(f[1],g[1]));
        return 0;
    }
  • 相关阅读:
    springboot配置redis缓存
    【spark】local模式运行
    mybatis从入门到精通(二) 增删查改
    学习设计模式
    学习设计模式
    mybatis从入门到精通(一) 入门
    学习NIO 之 使用方法
    学习 NIO 之 零拷贝
    Java并发
    学习设计模式
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6171335.html
Copyright © 2020-2023  润新知