• bzoj 1864: [Zjoi2006]三色二叉树


    Description

    此处输入图片的描述

    solution

    正解:递归+树型DP
    我们首先递归建树
    然后考虑树型DP,我们设绿色的节点为Y,非绿色为N
    我们神奇的发现:N会形成是很多条相互独立的链
    也就是说 Y 的下发有两个 N,这两个N一定可以不同,因为此题是二叉树,可以手推出
    所以DP状态只需表示为 (f[i][N/Y])
    (f[i][Y]=f[ls][N]+f[rs][N]+1)
    (f[i][N]=Max(f[ls][Y]+f[rs][N],f[rs][Y]+f[ls][N]))
    第二问改成Min即可

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    const int N=500005;
    char S[N];int n,ch[N][2],t=1,cnt=0,root;
    void dfs(int &x){
       x=++cnt;
       if(S[t]=='2'){
          t++;dfs(ch[x][0]);
          t++;dfs(ch[x][1]);
       }
       else if(S[t]=='1')t++,dfs(ch[x][0]);
    }
    int f[N],g[N];
    void hxy(int x,bool t){
       if(ch[x][0])hxy(ch[x][0],t);
       if(ch[x][1])hxy(ch[x][1],t);
       int ls=ch[x][0],rs=ch[x][1];
       f[x]=g[ls]+g[rs]+1;
       if(!t)g[x]=Max(g[ls]+f[rs],f[ls]+g[rs]);
       else g[x]=Min(g[ls]+f[rs],f[ls]+g[rs]);
    }
    void work()
    {
       scanf("%s",S+1);n=strlen(S+1);
       dfs(root);hxy(root,0);
       printf("%d ",Max(f[1],g[1]));
       hxy(root,1);
       printf("%d
    ",Min(f[1],g[1]));
    }
    
    int main()
    {
    	work();
    	return 0;
    }
    
    
  • 相关阅读:
    解决动态加载数据滑动失效
    js 判断手机横竖屏的实现方法(不依赖任何其他库)
    element-ui upload 图片格式验证 ,文件验证
    swiper 绑定点击事件 点击失效处理
    vue项目
    [Qt]自定义表头实现过滤功能
    字符串截取问题
    mysql超时机制
    nginx原理
    高可用集群(主从模式)
  • 原文地址:https://www.cnblogs.com/Hxymmm/p/7702219.html
Copyright © 2020-2023  润新知