P2585 [ZJOI2006]三色二叉树

题目描述

输入输出格式

输入格式:

输入文件名:TRO.IN

输入文件仅有一行,不超过10000个字符,表示一个二叉树序列。

输出格式:

输出文件名:TRO.OUT

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

输入输出样例

输入样例#1:

1122002010
输出样例#1:

5 2

思路:

  我们只关心绿色节点的数目,而红色蓝色可以看作无色,
  但是对于一个根节点和它的两个儿子,必须有一个绿色节点
  按照树形DP的思路,我们开一个二维数组dp[Maxn][2]
  一二维分别保存:
  该树的最优数目,该根节点涂绿色与不涂绿色[1表示涂绿色,0表示不涂]
  以最大绿色数为例:
      dp[i][0]=max(dp[left[i]][1]+dp[right[i]][0],dp[left[i]][0]+dp[right[i]][1]);
  如果不涂i节点, 那么i节点的子节点一定要有一个涂, 所以要么左为1右为0, 要么左为0右为1
    即:
      dp[i][1]=dp[left[i]][0]+dp[right[i]][0]+1
  如果涂i节点,那么它的两个儿子当然都不能涂! [别忘了还需要加上1,即:统计上i节点的绿色]
  最小绿色也是一个道理,只要把max改为min即可:
      dp[i][0]=min(dp[left[i]][1]+dp[right[i]][0],dp[left[i]][0]+dp[right[i]][1]);

坑点:

  数据范围是个大坑....应该开到10万才可以,他少打了个0....

上代码:

/*
Max
dp[i][1]=dp[left[i]][0]+dp[right[i]][0]+1
Min
dp[i][0]=min(dp[left[i]][1]+dp[right[i]][0],dp[left[i]][0]+dp[right[i]][1]);
*/
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std; const int Maxn = ;
const int Colors = ;
int rt,top=;
int L[Maxn],R[Maxn];
///第一维表示第几个点,第二维表示染什么颜色
int dpMax[Maxn][Colors],dpMin[Maxn][Colors]; int Max(int a, int b)
{return a > b ? a : b;}
int Min(int a, int b)
{return a < b ? a : b;} int build() {
top++;
int num=top;
int son=getchar()-'';
///默认为son==0时没有孩子,son==1时只有左孩子,son==2时左右均有.
if(son==) {
L[num]=;
R[num]=;
}
else if(son==) {
L[num]=build();
R[num]=;
}
else {
L[num]=build();
R[num]=build();
}
///返回孩子编号
return num;
}
///找较大值
void findMax(int u) {
if(dpMax[L[u]][]==-)
findMax(L[u]);
if(dpMax[R[u]][]==-)
findMax(R[u]);
dpMax[u][]=Max(dpMax[L[u]][]+dpMax[R[u]][],dpMax[L[u]][]+dpMax[R[u]][]);
dpMax[u][]=dpMax[L[u]][]+dpMax[R[u]][]+;
}
///找较小值
void findMin(int u) {
if(dpMin[L[u]][]==-)
findMin(L[u]);
if(dpMin[R[u]][]==-)
findMin(R[u]);
dpMin[u][]=Min(dpMin[L[u]][]+dpMin[R[u]][],dpMin[L[u]][]+dpMin[R[u]][]);
dpMin[u][]=dpMin[L[u]][]+dpMin[R[u]][]+;
} int main() {
rt=build();
memset(dpMax,-,sizeof(dpMax));
memset(dpMin,-,sizeof(dpMin));
///空节点为0,便于更新
dpMax[][]=dpMax[][]=;
dpMin[][]=dpMin[][]=;
findMax(rt);
findMin(rt);
int a1=Max(dpMax[rt][],dpMax[rt][]),
a2=Min(dpMin[rt][],dpMin[rt][]);
printf("%d %d",a1,a2);
return ;
}

luogu P2585 [ZJOI2006]三色二叉树的更多相关文章

  1. 【树形DP】洛谷P2585 [ZJOI2006] 三色二叉树

    [树形DP]三色二叉树 标签(空格分隔): 树形DP [题目] 一棵二叉树可以按照如下规则表示成一个由0.1.2组成的字符序列,我们称之为"二叉树序列S": 0 该树没有子节点 1 ...

  2. P2585 [ZJOI2006]三色二叉树

    题目描述 输入输出格式 输入格式: 输入文件名:TRO.IN 输入文件仅有一行,不超过500000个字符,表示一个二叉树序列. 输出格式: 输出文件名:TRO.OUT 输出文件也只有一行,包含两个数, ...

  3. 洛谷P2585 [ZJOI2006]三色二叉树

    题目描述 输入输出格式 输入格式: 输入文件名:TRO.IN 输入文件仅有一行,不超过10000个字符,表示一个二叉树序列. 输出格式: 输出文件名:TRO.OUT 输出文件也只有一行,包含两个数,依 ...

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

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

  5. [ZJOI2006]三色二叉树

    [ZJOI2006]三色二叉树 BZOJ luogu 分3种颜色讨论转移一下 #include<bits/stdc++.h> using namespace std; const int ...

  6. BZOJ1864[ZJOI2006]三色二叉树[树形DP]

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

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

    1864: [Zjoi2006]三色二叉树 Description Input 仅有一行,不超过500000个字符,表示一个二叉树序列. Output 输出文件也只有一行,包含两个数,依次表示最多和最 ...

  8. BZOJ 1864: [Zjoi2006]三色二叉树( 树形dp )

    难得的ZJOI水题...DFS一遍就行了... ----------------------------------------------------------------------- #inc ...

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

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

随机推荐

  1. 前端工程师应该知道的yarn知识

    yarn 是在工作中离不开的工具,但在工作中,很多人基本只会使用 yarn install,而且会手动删除 node-modules,或删除 yarn.lock 文件等不规范操作.本文将从一些基础的知 ...

  2. element-ui 中 table 鼠标悬停时背景颜色修改

    样式穿透: /deep/ .el-table tbody tr:hover>td { background-color: #颜色 }

  3. Python字符串的常用方法总结

    tring.capitalize() 把字符串的第一个字符大写 string.center(width) 返回一个原字符串居中,并使用空格填充至长度 width 的新字符串 , end=len(str ...

  4. 适配方案(五)适配的基础知识之设备像素比 dpr 与 1px 物理像素

    设备像素比 dpr 与 1px 物理像素 物理像素(physical pixel) 手机屏幕上显示的最小单元,该最小单元具有颜色及亮度的属性可供设置,iphone6.7.8 为:750 * 1334, ...

  5. LeetCode 腾讯精选50题--链表排序

    解题思路:归并 先把链表拆开,分为两部分,一直拆到只剩一个元素后,进行合并,利用一个临时节点记录重排后的链表的起始位置 合并不难,困难点在于如何拆分链表,自己的大体思路是利用两个指针,一个一次移动两位 ...

  6. js对象中属性调用.和[] 两种方式的区别

    JS 调用属性一般有两种方法——点和中括号的方法. 标准格式是对象.属性(不带双引号),注意一点的是:js对象的属性,key标准是不用加引号的,加也可以,特别的情况必须加,如果key数字啊,表达式啊等 ...

  7. 使用高德地图JS获取当前位置和经纬度

    先看效果,我做的是这样的,可以按地图位置来返回当前你点的位置(图一,二),也可以根据输入框的自动搜索(图三,四) HTML的代码: <div> <input type="t ...

  8. ARM与x86 CPU架构对比

    CISC(复杂指令集计算机)和RISC(精简指令集计算机)是当前CPU的两种架构.它们的区别在于不同的CPU设计理念和方法.早期的CPU全部是CISC架构,它的设计目的是CISC要用最少的机器语言指令 ...

  9. Flask debug 模式 PIN 码生成机制安全性研究笔记

    Flask debug 模式 PIN 码生成机制安全性研究笔记 0x00 前言 前几天我整理了一个笔记:Flask开启debug模式等于给黑客留了后门,就Flask在生产网络中开启debug模式可能产 ...

  10. linux上网时断时续问题

    [问题描述]打开百度比较慢:登录远程服务器操作一会儿就断了 [问题环境]ip自动获取 [问题分析]自己的ip地址被人占用了 [问题解决]1)重新手动配置一个新的ip    2)释放原来的ip,重新自动 ...