- 【题解】树形dp
虽然题目中一共有三种颜色,但是显然对于所要求的答案只有两种情况:绿色或非绿色
{状态} f[x][0]:第x个点非绿色;f[x][1]:第x个点为绿色;
{方程} 设x的左右儿子分别为 l[x] 和 r[x]:
f[x][0]=max/min(f[l[x]][1]+f[r[x]][0],f[l[x]][0]+f[r[x]][1]);
f[x][1]=f[l[x]][0]+f[r[x]][0]+1;
【呆马( ⊙—⊙ )】
#include <cstdio>
#include <iostream>
int n,ansmx,ansmn,l[500005],r[500005],f[500005][2];
void read(int x)
{
char ch=getchar();
if (ch=='0') return;
l[x]=++n;read(n);
if (ch=='1') return;
r[x]=++n;read(n);
}
void dpmx(int x)
{
if (!x) return;
dpmx(l[x]);dpmx(r[x]);
f[x][0]=std::max(f[l[x]][1]+f[r[x]][0],f[l[x]][0]+f[r[x]][1]);
f[x][1]=f[l[x]][0]+f[r[x]][0]+1;
}
void dpmn(int x)
{
if (!x) return;
dpmn(l[x]);dpmn(r[x]);
f[x][0]=std::min(f[l[x]][1]+f[r[x]][0],f[l[x]][0]+f[r[x]][1]);
f[x][1]=f[l[x]][0]+f[r[x]][0]+1;
}
int main()
{
read(n=1);
dpmx(1);ansmx=std::max(f[1][0],f[1][1]);
dpmn(1);ansmn=std::min(f[1][0],f[1][1]);
printf("%d %d\n",ansmx,ansmn);
return 0;
}