bzoj1864: [Zjoi2006]三色二叉树(树形DP)
程序员文章站
2022-06-24 12:43:17
题目: "1864: [Zjoi2006]三色二叉树" 解析: 用$f[u][0/1/2]$表示以$u$为根,颜色为绿/红/蓝时最多的数量 转移没啥好说的 $f[u][0] = max(f[l][1] + f[r][2], f[l][2] + f[r][1]) + 1$ $f[u][1/2] = m ......
题目:
解析:
用\(f[u][0/1/2]\)表示以\(u\)为根,颜色为绿/红/蓝时最多的数量
转移没啥好说的
\(f[u][0] = max(f[l][1] + f[r][2], f[l][2] + f[r][1]) + 1\)
\(f[u][1/2] = max(f[l][0] + f[r][2/1], f[l][2/1] + f[r][0])\)
最小值同理
建树的话递归建树就可以了
代码:
#include <bits/stdc++.h> using namespace std; const int n = 5e5 +10; int n, m, num, rt; int t[n][2], f[n][3]; char s[n]; inline void build(int &x) { x = ++num; if (s[x] == '0') return; if (s[x] == '1') build(t[x][0]); if (s[x] == '2') build(t[x][0]), build(t[x][1]); } void max(int u) { if (!u) return; int l = t[u][0], r = t[u][1]; max(l), max(r); f[u][0] = max(f[l][1] + f[r][2], f[l][2] + f[r][1]) + 1; f[u][1] = max(f[l][0] + f[r][2], f[l][2] + f[r][0]); f[u][2] = max(f[l][0] + f[r][1], f[l][1] + f[r][0]); } void min(int u) { if (!u) return; int l = t[u][0], r = t[u][1]; min(l), min(r); f[u][0] = min(f[l][1] + f[r][2], f[l][2] + f[r][1]) + 1; f[u][1] = min(f[l][0] + f[r][2], f[l][2] + f[r][0]); f[u][2] = min(f[l][0] + f[r][1], f[l][1] + f[r][0]); } int main() { cin >> (s + 1); build(rt); max(rt); cout << max(f[rt][0], max(f[rt][1], f[rt][2])) << " "; memset(f, 0, sizeof f); min(rt); cout << min(f[rt][0], min(f[rt][1], f[rt][2])); return 0; }
下一篇: Python调用百度AI实现颜值评分功能