Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

一棵二叉树可以按照如下规则表示成一个由0、1、2组成的字符序列,我们称之为“二叉树序列S”:

例如,下图所表示的二叉树可以用二叉树序列S=21200110来表示。

你的任务是要对一棵二叉树的节点进行染色。每个节点可以被染成红色、绿色或蓝色。并且,一个节点与其子节点的颜色必须不同,如果该节点有两个子节点,那么这两个子节点的颜色也必须不相同。给定一棵二叉树的二叉树序列,请求出这棵树中最多和最少有多少个点能够被染成绿色。

 Input

输入数据由多组数据组成。
每组数据仅有一行,不超过10000个字符,表示一个二叉树序列。

 Output

对于每组输入数据,输出仅一行包含两个整数,依次表示最多和最少有多少个点能够被染成绿色。

 Sample Input

1122002010

 Sample Output

5 2

【思路】先建树,然后进行树形DP;

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
const int inf=0x7777777;
const int colorn=;
enum color{green, red, blue, none};//enum 枚举名{ 枚举值表 };在枚举值表中应罗列出所有可用值。这些值也称为枚举元素。
struct node
{
node *left,*right;
int maxg[colorn],ming[colorn];
node()
{
left=right=NULL;
memset(maxg,,sizeof(int)*colorn);
memset(ming,,sizeof(int)*colorn);
}
};
typedef node *T;//指针类型定义:T等价于node *定义,T tree声明等价于node *a声明;
const int N=;
char *build(T &tree,char *a)//建树
{
if(a[]=='')
{
tree=new node();
return a+;
}
else if(a[]=='')
{
tree=new node();
return build(tree->left,a+);
}
else
{
tree=new node();
char *pos=build(tree->left,a+);
return build(tree->right,pos);
}
}
void TDP(T &tree)
{
if(tree==NULL) return ;
TDP(tree->left);
TDP(tree->right);
if(tree->left==NULL&&tree->right==NULL)
{
tree->maxg[green]=;tree->maxg[red]=tree->maxg[blue]=; tree->ming[green]=;tree->ming[red]=tree->ming[blue]=;
}
else if(tree->left!=NULL&&tree->right==NULL)
{
tree->maxg[green]=max(tree->left->maxg[red],tree->left->maxg[blue])+;
tree->maxg[red]=max(tree->left->maxg[blue],tree->left->maxg[green]);
tree->maxg[blue]=max(tree->left->maxg[green],tree->left->maxg[red]); tree->ming[green]=min(tree->left->ming[red],tree->left->ming[blue])+;
tree->ming[red]=min(tree->left->ming[blue],tree->left->ming[green]);
tree->ming[blue]=min(tree->left->ming[red],tree->left->ming[green]);
}
else if(tree->right!=NULL&&tree->left==NULL)
{
tree->maxg[green]=max(tree->right->maxg[red],tree->right->maxg[blue])+;
tree->maxg[red]=max(tree->right->maxg[blue],tree->right->maxg[green]);
tree->maxg[blue]=max(tree->right->maxg[green],tree->right->maxg[red]); tree->ming[green]=min(tree->right->ming[red],tree->right->ming[blue])+;
tree->ming[red]=min(tree->right->ming[blue],tree->right->ming[green]);
tree->ming[blue]=min(tree->right->ming[red],tree->right->ming[green]);
}
else
{
tree->maxg[green]=max(tree->right->maxg[red]+tree->left->maxg[blue],tree->right->maxg[blue]+tree->left->maxg[red])+;
tree->maxg[red]=max(tree->right->maxg[green]+tree->left->maxg[blue],tree->right->maxg[blue]+tree->left->maxg[green]);
tree->maxg[blue]=max(tree->right->maxg[green]+tree->left->maxg[red],tree->right->maxg[red]+tree->left->maxg[green]); tree->ming[green]=min(tree->right->ming[red]+tree->left->ming[blue],tree->right->ming[blue]+tree->left->ming[red])+;
tree->ming[red]=max(tree->right->ming[green]+tree->left->ming[blue],tree->right->ming[blue]+tree->left->ming[green]);
tree->ming[blue]=max(tree->right->ming[green]+tree->left->ming[red],tree->right->ming[red]+tree->left->ming[green]); }
}
void destroy(T &tree)
{
if(tree==NULL) return ;
destroy(tree->left);
destroy(tree->right);
delete tree;
}
int main()
{
char a[N];
while(~scanf("%s",a))
{
T tree=NULL;
build(tree,a); TDP(tree);
int maxx=-inf,minn=inf;
for(int i=;i<colorn;i++)
{
if(tree->maxg[i]>maxx) maxx=tree->maxg[i];
if(tree->ming[i]<minn) minn=tree->ming[i];
}
printf("%d %d\n",maxx,minn);
destroy(tree);
}
return ;
}

三色二叉树_树形DP的更多相关文章

  1. BZOJ_1864_[Zjoi2006]三色二叉树_树形DP

    BZOJ_1864_[Zjoi2006]三色二叉树_树形DP 题意: 分析:递归建树,然后DP,从子节点转移. 注意到红色和蓝色没有区别,因为我们可以将红蓝互换而方案是相同的.这样的话我们只需要知道当 ...

  2. 三色二叉树 ---伪树形dp

    题目描述 一棵二叉树可以按照如下规则表示成一个由0.1.2组成的字符序列,我们称之为"二叉树序列S": 0 该树没有子节点 1S1 该树有一个子节点,S1为其二叉树序列 1S1S2 ...

  3. 洛谷P2585 [ZJOI2006]三色二叉树(树形dp)

    传送门 设$dp[u][i]$表示点$u$颜色为$i$时最多(最少)的绿点个数(这里用$0$表示绿点) 然后直接用树形dp就可以了 记得把情况讨论清楚 //minamoto #include<b ...

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

    Description Input 仅有一行,不超过500000个字符,表示一个二叉树序列. Output 输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色. Sample ...

  5. 1864. [ZJOI2006]三色二叉树【树形DP】

    Description Input 仅有一行,不超过500000个字符,表示一个二叉树序列. Output 输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色. Sample ...

  6. BZOJ 1864:[Zjoi2006]三色二叉树(树DP)

    三色二叉树 问题描述 输入 仅有一行,不超过500000个字符,表示一个二叉树序列. 输出 输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色. 样例输入 1122002010 ...

  7. [bzoj1812][IOI2006]riv_多叉树转二叉树_树形dp

    riv bzoj-1812 IOI-2006 题目大意:给定一棵n个点树,要求在上面建立k个收集站.点有点权,边有边权,整棵树的代价是每个点的点权乘以它和它的最近的祖先收集站的距离积的和. 注释:$1 ...

  8. BZOJ 1864 三色二叉树 - 树型dp

    传送门 题目大意: 给一颗二叉树染色红绿蓝,父亲和儿子颜色必须不同,两个儿子颜色必须不同,问最多和最少能染多少个绿色的. 题目分析: 裸的树型dp:\(dp[u][col][type]\)表示u节点染 ...

  9. 【BZOJ-1864】三色二叉树 树形DP

    1864: [Zjoi2006]三色二叉树 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 659  Solved: 469[Submit][Status] ...

随机推荐

  1. javasE学习笔记:关键字super的使用

    /* super 的作用: 1 . super可以在子类中引用父类的成员,通过 .的方式和属性.this相对应. 2. 在子类的构造方法中可以可使用super(参数列表)语句调用父类的构造方法 3. ...

  2. 个人介绍和GitHub

    基本信息: 姓名:陈晖 学号:1413042068 班级:网工143 兴趣爱好:看小说,打游戏,听古风音乐,打羽毛球,骑行等 个人编程能力不高,写的代码都是作业…… GitHub注册流程: 对于Git ...

  3. jQuery制作瀑布流(转)

    “瀑布流布局”随着pinterest网的流行而出名,现在国内使用这种风格布局的网站也越来越多,比如说Mark之,蘑菇街,点点网,哇哦等等.我第一次听到这个布局名称是来自于“乔花写的<瀑布流布局浅 ...

  4. [转]RAID技术介绍和总结

    以下内容转自伯乐在线:http://blog.jobbole.com/83808/ 原文出处: 涯余(@若东临于沧海) ---------------------------------------- ...

  5. Windows API 文件处理

    CloseHandle 关闭一个内核对象.其中包括文件.文件映射.进程.线程.安全和同步对象等 CompareFileTime 对比两个文件的时间 CopyFile 复制文件 CreateDirect ...

  6. Nginx介绍

    原文:http://www.aosabook.org/en/nginx.html 作者: Andrew Alexeev nginx(发音"engine x")是俄罗斯软件工程师Ig ...

  7. hdu 4618 Palindrome Sub-Array

    http://acm.hdu.edu.cn/showproblem.php?pid=4618 直接DP+记忆化 虽然时间复杂度看起来是300^4 但实际执行起来要远远小于这个值 所有可以水过 代码: ...

  8. 一模 (6) day2

    第一题: 题目大意:求最长公共上升子序列(LICS): 解题过程: 1.一开始想到模仿求最长公共子序列的方法,F[i][j]表示A串前i个,B串前j个的最长公共子序列,很明显当A[i]!= B[j]时 ...

  9. 2.精通前端系列技术之JS模块化开发-深入学习seaJs(四)

    深入学习seajs 配置信息 alias : 别名配置 paths : 路径配置 vars : 变量配置 map : 映射配置 preload : 预加载项 debug : 调试模式 base : 基 ...

  10. 使用ROS节点(五)

    先启动roscore roscore 为了获取节点信息,可以使用rosnode命令 $ rosnode 获取得一个可接受参数清单