• BZOJ-1864-[Zjoi2006]三色二叉树(树形dp)


    Description

    Input

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

    Output

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

    Sample Input

    1122002010

    Sample Output

    5 2

    HINT

     

    Source

     

    题解

    这道题我们考虑dp

    我们先把树给构造出来(可以用栈,也可以用dfs)

    建完树后,我们用f[i][0/1/2][0]表示i节点填绿/蓝/红色的最小答案,f[i][0/1/2][1]表示i节点填绿/蓝/红色的最大答案

    我们考虑i节点从两个儿子转移

    f[i][0][0]=min(f[s1][1][0]+f[s2][2][0],f[s1][2][0]+f[s2][1][0])

    f[i][1][0]=min(f[s1][0][0]+f[s2][2][0],f[s1][2][0]+f[s2][0][0])

    f[i][2][0]=min(f[s1][0][0]+f[s2][1][0],f[s1][1][0]+f[s2][0][0])

    f[i][0/1/2][1]转移同理

     1 #include<bits/stdc++.h>
     2 #define N 500005
     3 using namespace std;
     4 int tot,top;
     5 int Stack[N];
     6 int f[N][3][2];
     7 char s[N];
     8 int main(){
     9     scanf("%s",s+1);
    10     int len=strlen(s+1);
    11     for (int i=len;i>=1;i--)
    12         if (s[i]=='2'){
    13             int x=Stack[top],y=Stack[--top];
    14             tot++;
    15             f[tot][0][0]=min(f[x][1][0]+f[y][2][0],f[x][2][0]+f[y][1][0])+1;
    16             f[tot][1][0]=min(f[x][2][0]+f[y][0][0],f[x][0][0]+f[y][2][0]);
    17             f[tot][2][0]=min(f[x][1][0]+f[y][0][0],f[x][0][0]+f[y][1][0]);
    18             f[tot][0][1]=max(f[x][1][1]+f[y][2][1],f[x][2][1]+f[y][1][1])+1;
    19             f[tot][1][1]=max(f[x][2][1]+f[y][0][1],f[x][0][1]+f[y][2][1]);
    20             f[tot][2][1]=max(f[x][1][1]+f[y][0][1],f[x][0][1]+f[y][1][1]);
    21             Stack[top]=tot;
    22         } else
    23         if (s[i]=='1'){
    24             int x=Stack[top];
    25             tot++;
    26             f[tot][0][0]=min(f[x][1][0],f[x][2][0])+1;
    27             f[tot][1][0]=min(f[x][0][0],f[x][2][0]);
    28             f[tot][2][0]=min(f[x][0][0],f[x][1][0]);
    29             f[tot][0][1]=max(f[x][1][1],f[x][2][1])+1;
    30             f[tot][1][1]=max(f[x][0][1],f[x][2][1]);
    31             f[tot][2][1]=max(f[x][0][1],f[x][1][1]);
    32             Stack[top]=tot;
    33         } else{
    34             tot++;
    35             f[tot][0][0]=f[tot][0][1]=1;
    36             Stack[++top]=tot;
    37         }
    38     int Max=max(f[tot][0][1],max(f[tot][1][1],f[tot][2][1]));
    39     int Min=min(f[tot][0][0],min(f[tot][1][0],f[tot][2][0]));
    40     printf("%d %d",Max,Min);
    41     return 0;
    42 } 
    View Code
  • 相关阅读:
    自我介绍篇
    iOS支付宝集成时遇到的问题整理(2)
    iOS支付宝集成时遇到的问题整理(1)
    注册登录时本地图片验证码
    集成ZBar时容易遇到的问题以及解决方法
    iOS解析数据时Error=3840
    iOS开发中的一些定时器
    二维码扫描利用ZBar实现
    去除UITableView中多余的分割线或者隐藏cell间的分割线
    iOS 中二维码扫描
  • 原文地址:https://www.cnblogs.com/zhuchenrui/p/7794835.html
Copyright © 2020-2023  润新知