Luogu P2585 [ZJOI2006]三色二叉树

题目链接:传送门

很容易写dfs
如果根节点为绿色则子节点都不能为绿色
如果根节点不为绿色则子节点有一个可以为绿色
建好树直接搜就可以
但只有40分
需要加记忆化

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define A 1000010
#define B 2010

using namespace std;
typedef long long ll;
char s[A];
int ch[A][2], cnt, rt, f[A][2], g[A][2];
void init(int &now) {
	now = ++cnt;
	int x = s[cnt] - '0';
	if (x == 0) return;
	else if (x == 1) init(ch[now][1]);
	else if (x == 2) init(ch[now][0]), init(ch[now][1]);
}
int maxx(int ifg, int son) {
	if (son == 0) return 0;
	if (~f[son][ifg]) return f[son][ifg];
	if (ifg) return f[son][ifg] = maxx(!ifg, ch[son][0]) + maxx(!ifg, ch[son][1]) + 1;
	else return f[son][ifg] = max(maxx(!ifg, ch[son][0]) + maxx(ifg, ch[son][1]), maxx(ifg, ch[son][0]) + maxx(!ifg, ch[son][1]));
}
int minn(int ifg, int son) {
	if (son == 0) return 0;
	if (~g[son][ifg]) return g[son][ifg];
	if (ifg) return g[son][ifg] = minn(!ifg, ch[son][0]) + minn(!ifg, ch[son][1]) + 1;
	else return g[son][ifg] = min(minn(!ifg, ch[son][0]) + minn(ifg, ch[son][1]), minn(ifg, ch[son][0]) + minn(!ifg, ch[son][1]));
}

int main(int argc, char const *argv[]) {
	cin >> (s + 1); init(rt); memset(f, -1, sizeof f); memset(g, -1, sizeof g);
	cout << max(maxx(0, 1), maxx(1, 1)) << " " << min(minn(0, 1), minn(1, 1)) << endl;
}

你可能感兴趣的:(记忆化搜索,Dfs,Luogu)