BZOJ 1864 三色二叉树(树DP)
2015-07-13 21:06
435 查看
Description
Input
仅有一行,不超过500000个字符,表示一个二叉树序列。Output
输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色。Sample Input
1122002010Sample Output
5 2树DP问题:经典的去最大和最小=-=没啥说的,递归建树。
dp[i][0]: i节点不为绿色获得的最大收益dp[i][1]:i节点为绿色获得的最大收益
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<string> #include<iostream> #include<queue> #include<cmath> #include<map> #include<stack> #include<set> using namespace std; #define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define CLEAR( a , x ) memset ( a , x , sizeof a ) const int INF=0x3f3f3f3f; typedef long long LL; const int maxn=1e5+100; int l[maxn],r[maxn],sz; LL dp[maxn][2];//三种颜色的最多的那个1:NOT 绿 2:绿 char str[maxn]; void dfs(int x) { if(str[x-1]=='0') return ; sz++;l[x]=sz; dfs(sz); if(str[x-1]=='2') { sz++; r[x]=sz; dfs(sz); } } void hehe1(int u) { if(!u) return ; dp[u][1]=1; dp[u][0]=0; hehe1(l[u]); hehe1(r[u]); dp[u][1]+=dp[l[u]][0]+dp[r[u]][0]; dp[u][0]+=max(dp[l[u]][0]+dp[r[u]][1],dp[l[u]][1]+dp[r[u]][0]);//选其他颜色 } void hehe2(int u) { if(!u) return ; dp[u][1]=1; dp[u][0]=0; hehe2(l[u]); hehe2(r[u]); dp[u][1]+=dp[l[u]][0]+dp[r[u]][0]; dp[u][0]+=min(dp[l[u]][0]+dp[r[u]][1],dp[l[u]][1]+dp[r[u]][0]);//选其他颜色 } int main() { int mi,mx; while(~scanf("%s",str)) { CLEAR(l,0); CLEAR(r,0); dfs(sz=1); CLEAR(dp,0); hehe1(1); mx=max(dp[1][1],dp[1][0]); hehe2(1); mi=min(dp[1][1],dp[1][0]); printf("%d %d\n",mx,mi); } return 0; }
相关文章推荐
- Android AOSP输入法(LatinIME)输入流程二
- socket网络编程基础小记
- Java实现堆排序(大根堆)
- 兼容性问题
- java中map的两种遍历
- Fiddler中返回数据乱码问题
- 最大的疑问:下一跳???
- MFC消息分类及处理方式
- 第二章
- 【三】继承+构造器
- ros系列笔记
- 入侵某邮网络例子
- Python-装饰器
- HTTP长链接
- Java内部类总结 (吐血之作)
- 【转】【Android开发经验】Android相关好博客推荐--跟随大神的脚步才能成为大神--加油!
- OnClientClick和OnClick的区别
- OnClientClick和OnClick的区别
- @Autowired与@Qualifer的使用区别备忘
- 视觉直观感受7种常用排序算法