当前位置: 移动技术网 > IT编程>脚本编程>Python > CSP2019 T2 括号树

CSP2019 T2 括号树

2020年10月23日  | 移动技术网IT编程  | 我要评论
题目分析像我这种菜鸡,谁会直接想正解啊先看一下部分分,哇 55pts 还是条链再一看1e5,那必须DP啊dp[i][0/1]表示到第i位的总共合法括号,第i位是否匹配成功dp[i][0/1]表示到第i位的总共合法括号,第i位是否匹配成功dp[i][0/1]表示到第i位的总共合法括号,第i位是否匹配成功显然再加上一个栈即可完成转移dp[i][1]=max(dp[i−1][1],dp[i−1][0])+dp[stck[l−−]−1][0]+1dp[i][1]=max(dp[i-1][1],dp[

题目

分析

  • 像我这种菜鸡,谁会直接想正解啊
  • 先看一下部分分,哇 55pts 还是条链
  • 再一看1e5,那必须DP
  • d p [ i ] [ 0 / 1 ] 表 示 到 第 i 位 的 总 共 合 法 括 号 , 第 i 位 是 否 匹 配 成 功 dp[i][0/1]表示到第i位的总共合法括号,第i位是否匹配成功 dp[i][0/1]ii
  • 显然再加上一个栈即可完成转移
  • d p [ i ] [ 1 ] = m a x ( d p [ i − 1 ] [ 1 ] , d p [ i − 1 ] [ 0 ] ) + d p [ s t c k [ l − − ] − 1 ] [ 0 ] + 1 dp[i][1]=max(dp[i-1][1],dp[i-1][0])+dp[stck[l--]-1][0]+1 dp[i][1]=max(dp[i1][1],dp[i1][0])+dp[stck[l]1][0]+1
  • 但是我们发现因为我们设定的DP方程具有前缀和的性质,所以在 ()())()() 时,会出错
  • 所以我们再开个数组表示在这个位置,有多少个连一起的 ()()
  • 所以,我们改进一下
  • d p [ i ] [ 1 ] = m a x ( d p [ i − 1 ] [ 1 ] , d p [ i − 1 ] [ 0 ] ) + ( a d [ i ] = a d [ s t c k [ l − − ] − 1 ] + 1 ) dp[i][1]=max(dp[i-1][1],dp[i-1][0])+(ad[i]=ad[stck[l--]-1]+1) dp[i][1]=max(dp[i1][1],dp[i1][0])+(ad[i]=ad[stck[l]1]+1)
  • 就有55pts了
  • 这时想一下正解,发现,在树上只是改变了序列的顺序,和树的性质没什么关系
  • 那么直接照搬就行了(注意回溯

代码

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
struct node{
	int next,to;
}a[N<<1];
long long dp[N][4],ad[N];
long long num[N];
int n;
int ln[N],tot;
long long ans=0;
int f[N],fa[N];
char t[N];
int l;
int stck[N];
inline void add(int x,int y) {a[++tot].next=ln[x]; ln[x]=tot; a[tot].to=y;}
inline int read()
{
	int num=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-') f=-1; ch=getchar();}
	while(ch>='0'&&ch<='9') {num=(num<<1)+(num<<3)+ch-'0'; ch=getchar();}
	return num*f;
}
void dfs(int x)
{
	int flag=0;
	if(!f[x])
	{
		if(l)
		{
			flag=stck[l--];
			ad[x]=ad[fa[flag]]+1;
		}
	}
	else if(f[x]) stck[++l]=x;
	num[x]=num[fa[x]]+ad[x];
	for(int i=ln[x];i;i=a[i].next)
	{
		int y=a[i].to;
		dfs(y);
	}
	if(flag) stck[++l]=flag;
	else if(l) l--;
}
int main()
{
	n=read();
	for(int i=1;i<=n;i++) cin>>t[i];
	for(int i=1;i<=n;i++) t[i]=='('?f[i]=1:f[i]=0;
	for(int i=1;i<n;i++) 
	{
		int x=read(); add(x,i+1); fa[i+1]=x;
	}
	dfs(1);
	for(int i=1;i<=n;i++) ans^=(long long)i*num[i];
	printf("%lld",ans);
	/*
	if(!flag)
	{
		int l=0;
		long long now=0;
		for(int i=1;i<=n;i++)
		{
			if(!f[i]&&l) dp[i][1]=max(dp[i-1][1],dp[i-1][0])+(ad[i]=ad[stck[l--]-1]+1);			
			else if(!f[i]&&!l) dp[i][0]=max(dp[i-1][1],dp[i-1][0]),l=0;
			else if(f[i]) dp[i][0]=max(dp[i-1][0],dp[i-1][1]),stck[++l]=i;
			ans^=(long long)i*max(dp[i][0],dp[i][1]);
		} 
		printf("%lld\n",ans);
	}
	*/
	return 0;
}

鸽子桌折,QvQ,嘻嘻~

一年前考的今天才补 呜呜呜菜死我了

本文地址:https://blog.csdn.net/qq_45516669/article/details/109235838

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网