【DP】【树形DP】Splot

题意:

【DP】【树形DP】Splot
【DP】【树形DP】Splot


分析:

很有毒的树形DP题

每个串联和并联都可以看作:新加一个点,将串(并)联的两个点作为新点的儿子。

然后,可以记录4种状态进行树形DP
【DP】【树形DP】Splot
转移分串并联讨论一下就可以了。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define SF scanf
#define PF printf
#define MAXN 1000010
#define INF 0x3FFFFFFF
using namespace std;
char s[MAXN];
int tot;
struct node{
	int typ;
	node *ch[2];
	int dp[5];
	int f1,f2,siz;	
}Pool[MAXN];
node *ncnt=Pool,*rt=Pool;
char* build_tree(node *&x,char *s){
	x=++ncnt;
	if(*s=='P'){
		s++;
		x->typ=1;
		x->f1=('o'!=*s++);
		s++;
		s=build_tree(x->ch[0],s);
		s=build_tree(x->ch[1],s);
		s++;
		x->f2=('o'!=*s++); 
		s++;
		x->siz=x->f1+x->f2;
	}
	else if(*s=='S'){
		s++;
		x->typ=2;
		s=build_tree(x->ch[0],s);
		s=build_tree(x->ch[1],s);
		s++;
	}
	else if(*s=='o'){
		s++;
		x->typ=3;
	}
	else if(*s=='x'){
		s++;
		x->typ=4;
		x->siz=1;
	}
	return s;
}
int gmax(int &x,int y){
	x=max(x,y);
}	
void dfs(node *x){
	x->dp[1]=x->dp[2]=x->dp[3]=x->dp[4]=-INF;
	if(x->typ==4){
		x->dp[1]=x->dp[2]=x->dp[3]=1;
		return ;
	}
	if(x->typ==3){
		x->dp[1]=x->dp[2]=x->dp[3]=1;
		x->dp[4]=0;
		return ;
	}
	dfs(x->ch[0]);
	dfs(x->ch[1]);
	x->siz=x->siz+x->ch[0]->siz+x->ch[1]->siz;
	node *l=x->ch[0];
	node *r=x->ch[1];
	if(x->typ==2){
		if(r->siz==0) gmax(x->dp[1],l->dp[1]);
		if(l->siz==0) gmax(x->dp[2],r->dp[2]);
		gmax(x->dp[1],l->dp[4]+r->dp[1]);
		gmax(x->dp[2],l->dp[2]+r->dp[4]);
		gmax(x->dp[3],l->dp[1]+r->dp[2]);
		gmax(x->dp[3],l->dp[3]+r->dp[4]);
		gmax(x->dp[3],l->dp[4]+r->dp[3]);
		gmax(x->dp[4],l->dp[4]+r->dp[4]);
	}
	else if(x->typ==1){
		for(int mask=0;mask<4;mask++){
			int s=mask&1;
			int t=mask&2;
			if(s==0&&x->f1) continue;
			if(t==0&&x->f2) continue;
			if(s&&t){
				if(l->siz==0&&r->siz==0)
					gmax(x->dp[3],2);
			}
			else if(s){
				if(l->siz==0&&r->siz==0)
					gmax(x->dp[1],1);
				gmax(x->dp[2],l->dp[4]+r->dp[2]+1);
				gmax(x->dp[2],l->dp[2]+r->dp[4]+1);
				gmax(x->dp[3],l->dp[2]+r->dp[2]+1);
			}
			else if(t){
				if(l->siz==0&&r->siz==0)
					gmax(x->dp[2],1);
				gmax(x->dp[1],l->dp[4]+r->dp[1]+1);
				gmax(x->dp[1],l->dp[1]+r->dp[4]+1);
				gmax(x->dp[3],l->dp[1]+r->dp[1]+1);
			}
			else{
				gmax(x->dp[1],l->dp[1]+r->dp[1]);
				gmax(x->dp[1],l->dp[4]+r->dp[3]);
				gmax(x->dp[1],l->dp[3]+r->dp[4]);
				
				gmax(x->dp[2],l->dp[2]+r->dp[2]);
				gmax(x->dp[2],l->dp[3]+r->dp[4]);
				gmax(x->dp[2],l->dp[4]+r->dp[3]);
				
				gmax(x->dp[3],l->dp[3]+r->dp[3]);
				
				gmax(x->dp[4],l->dp[4]+r->dp[3]);
				gmax(x->dp[4],l->dp[3]+r->dp[4]);
			}
		}
	}
}
int main(){
	freopen("splot.in","r",stdin);
	freopen("splot.out","w",stdout);
	SF("%s",s);	
	build_tree(rt,s);
	dfs(rt);
	PF("%d",rt->dp[1]);
}