1 条题解
-
0
自动搬运
来自洛谷,原作者为

hs_black
Go for broke搬运于
2025-08-24 21:39:21,当前版本为作者最后更新于2019-10-01 17:38:16,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
介绍一个无建树做法
个人认为我的代码比较易懂(
简直不需要注释)定义dp[x][0/1/2] 分别为x节点染绿 /红 /蓝 情况下子树中最多有几个点被染成绿色
类似的 f[x][0/1/2] 为最少有几个点
见代码:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N = 500050; char s[N]; int dp[N][4], f[N][4], cnt; int ans1 = 1; void dfs(int x) { if (s[x] == '0') {//叶节点 f[x][0] = dp[x][0] = 1; return; } dfs(++cnt); //左儿子编号为x+1 if (s[x] == '1') { //一个儿子 dp[x][0] = max(dp[x+1][1], dp[x+1][2])+1; dp[x][1] = max(dp[x+1][0], dp[x+1][2]); dp[x][2] = max(dp[x+1][0], dp[x+1][1]); //儿子染另外一种颜色 // 上方代码完全是复制一遍到下面 f[x][0] = min(f[x+1][1], f[x+1][2])+1; f[x][1] = min(f[x+1][0], f[x+1][2]); f[x][2] = min(f[x+1][0], f[x+1][1]); } else { //右儿子编号为k int k = ++cnt; dfs(k); dp[x][0] = max(dp[x+1][1] + dp[k][2], dp[x+1][2] + dp[k][1]) + 1; dp[x][1] = max(dp[x+1][0] + dp[k][2], dp[x+1][2] + dp[k][0]); dp[x][2] = max(dp[x+1][0] + dp[k][1], dp[x+1][1] + dp[k][0]); f[x][0] = min(f[x+1][1] + f[k][2], f[x+1][2] + f[k][1]) + 1; f[x][1] = min(f[x+1][0] + f[k][2], f[x+1][2] + f[k][0]); f[x][2] = min(f[x+1][0] + f[k][1], f[x+1][1] + f[k][0]); } ans1 = max(ans1, dp[x][0]); } int main() { scanf ("%s", s + 1); dfs(++cnt); cout << ans1 << ' ' << min(f[1][0], min(f[1][1], f[1][2])) << endl; return 0; }
- 1
信息
- ID
- 1621
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 4
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者