zoukankan      html  css  js  c++  java
  • bzoj1864:[Zjoi2006]三色二叉树

    传送门

    简单树形dp
    (f[i][j])为当前为(i)号节点,当前颜色是(j)
    转移枚举一下子节点颜色,判断一下就好了
    代码:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int l[500001],r[500001],now=1,d[500001][3];
    char n[500002];
    void build(int x)
    {
    	if(n[now]=='0')return ;
    	else if(n[now]=='1')l[x]=++now,build(now);
    	else if(n[now]=='2')l[x]=++now,build(now),r[x]=++now,build(now);
    }
    void maxx(int x)
    {
    	if(l[x]&&r[x])maxx(l[x]),maxx(r[x]);
    	if(l[x]&&!r[x])maxx(l[x]);
    	if(r[x]&&!l[x])maxx(r[x]);
    	if(!r[x]&&!l[x])
    	{
    		d[x][1]=1;
    		return ;
    	}
    	if(l[x]&&r[x])
    	{
    		d[x][0]=max(d[l[x]][1]+d[r[x]][2],d[l[x]][2]+d[r[x]][1]);
    		d[x][1]=max(d[l[x]][0]+d[r[x]][2],d[l[x]][2]+d[r[x]][0])+1;
    		d[x][2]=max(d[l[x]][1]+d[r[x]][0],d[l[x]][0]+d[r[x]][1]);
    	}
    	if(l[x]&&!r[x])
    	{
    		d[x][0]=max(d[l[x]][1],d[l[x]][2]);
    		d[x][1]=max(d[l[x]][0],d[l[x]][2])+1;
    		d[x][2]=max(d[l[x]][1],d[l[x]][0]);
    	}
    	if(r[x]&&!l[x])
    	{
    		d[x][0]=max(d[r[x]][1],d[r[x]][2]);
    		d[x][1]=max(d[r[x]][0],d[r[x]][2])+1;
    		d[x][2]=max(d[r[x]][1],d[r[x]][0]);
    	}
    }
    void minn(int x)
    {
    	if(l[x]&&r[x])minn(l[x]),minn(r[x]);
    	if(l[x]&&!r[x])minn(l[x]);
    	if(r[x]&&!l[x])minn(r[x]);
    	if(!r[x]&&!l[x])return ;
    	if(l[x]&&r[x])
    	{
    		d[x][0]=min(d[l[x]][1]+d[r[x]][2],d[l[x]][2]+d[r[x]][1]);
    		d[x][1]=min(d[l[x]][0]+d[r[x]][2],d[l[x]][2]+d[r[x]][0])+1;
    		d[x][2]=min(d[l[x]][1]+d[r[x]][0],d[l[x]][0]+d[r[x]][1]);
    	}
    	if(l[x]&&!r[x])
    	{
    		d[x][0]=min(d[l[x]][1],d[l[x]][2]);
    		d[x][1]=min(d[l[x]][0],d[l[x]][2])+1;
    		d[x][2]=min(d[l[x]][1],d[l[x]][0]);
    	}
    	if(r[x]&&!l[x])
    	{
    		d[x][0]=min(d[r[x]][1],d[r[x]][2]);
    		d[x][1]=min(d[r[x]][0],d[r[x]][2])+1;
    		d[x][2]=min(d[r[x]][1],d[r[x]][0]);
    	}
    }
    int main()
    {
    	scanf("%s",n+1);
    	build(1);maxx(1);
    	printf("%d ",max(d[1][1],max(d[1][0],d[1][2])));
    	minn(1);
    	printf("%d",min(d[1][1],min(d[1][0],d[1][2])));
    }
    
  • 相关阅读:
    java并发编程
    Linux C++服务器端进程SDK
    定时器SDK
    Redis3.0集群方案分析
    DES
    生成验证码
    MVC Ajax.BeginForm 提交上传图片
    EF LIKE 查询
    JS 60秒后重发送验证码
    EF 指定字段修改
  • 原文地址:https://www.cnblogs.com/lcxer/p/10492284.html
Copyright © 2011-2022 走看看