2021.08.30 膜你赛

2021.08.30 膜你赛

regular

Solution

Dp,设 (f[i][j][k]) 表示 插入i个括号,使用原序列j个括号,当前左括号比右括号多 k 个的数量的方案数。

Code

/*
* @Author: smyslenny
* @Date:    2021.08.30
* @Title:   
* @Main idea:
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <vector>

#define int long long
#define INF 0x3f3f3f3f
#define orz cout<<"LKP AK IOI
"
#define MAX(a,b) (a)>(b)?(a):(b)
#define MIN(a,b) (a)>(b)?(a):(b)

using namespace std;
const int mod=1e9+7;
const int M=205;
int n,len,sum[M];
char s[M]; 
int read()
{
	int x=0,y=1;
	char c=getchar();
	while(c<'0' || c>'9') {if(c=='-') y=0;c=getchar();}
	while(c>='0' && c<='9') { x=x*10+(c^48);c=getchar();}  
	return y?x:-x;
}
int sta[M];
namespace substack1{
	int res,Ans;
	void check()
	{
		int x=1;
		for(int i=1;i<=n<<1;i++)
			if(sta[i]==sum[x]) x++;
		if(x>len) Ans++;
	}
	void dfs(int x,int res)
	{
		if(x>n*2)
		{
			if(res) return;
			else check();
			return;
		}
		if(res==0) 
		{
			sta[x]=0;
			dfs(x+1,res+1);
			return;
		}
		sta[x]=1;
		dfs(x+1,res-1);
		sta[x]=0;
		dfs(x+1,res+1);
	}
	void main()
	{
		for(int i=1;i<=len;i++) sum[i]=s[i]=='('?0:1;
		dfs(1,0);
		printf("%lld
",Ans);
	}
		
}
namespace substack2{

	int f[M][M][M];
	void main()
	{
		//f[i][j][k] 插入的括号的数量,使用的与序列的数量,当前左括号比右括号多 k 个的数量 
		f[0][0][0]=1;
		for(int i=0;i<=2*n-len;i++)
			for(int j=0;j<=len;j++)
				for(int k=0;k<=n;k++)
				{
					if(s[j]=='(' && j<len)//当前是左括号并且当前序列中加入的括号数比原序列括号数小 
						f[i][j+1][k+1]=(f[i][j][k]+f[i][j+1][k+1])%mod;//加入这个左括号 
					else 
						f[i+1][j][k+1]=(f[i][j][k]+f[i+1][j][k+1])%mod;//当前是右括号,且左括号的数量大于右括号,插入一个左括号 
					if(k>0)
					{
						if(s[j]==')' && j<len)//如果是右括号,并且k>0,就将该右括号放入最终序列
							f[i][j+1][k-1]=(f[i][j][k]+f[i][j+1][k-1])%mod;
						else
							f[i+1][j][k-1]=(f[i][j][k]+f[i+1][j][k-1])%mod;//当前枚举的是一个左括号,插入一个右括号 
					} 
				}
		printf("%lld
",f[2*n-len][len][0]);
	}
}
signed main()
{
//	freopen("regular.in","r",stdin);
//	freopen("regular.out","w",stdout);
	n=read();
	scanf("%s",s+1);
	len=strlen(s+1);
	if(len==n<<1 && s[1]==')') printf("0
"); 
	else if(n<=10) substack1::main();
	else substack2::main();
	return 0;
}

number

Solution

(2^n) 的暴力。剩下的不回了。

 /*
* @Author: smyslenny
* @Date:    2021.08.30
* @Title:   
* @Main idea:
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <vector>

#define int long long
#define INF 0x3f3f3f3f
#define orz cout<<"LKP AK IOI
"
#define MAX(a,b) (a)>(b)?(a):(b)
#define MIN(a,b) (a)>(b)?(a):(b)

using namespace std;
const int mod=998244353;
const int M=1005;
int n,m;
int read()
{
	int x=0,y=1;
	char c=getchar();
	while(c<'0' || c>'9') {if(c=='-') y=0;c=getchar();}
	while(c>='0' && c<='9') { x=x*10+(c^48);c=getchar();}
	return y?x:-x;
}
struct ed{
	int l,r,x;
}sz[M];
struct node{
	int num,las[M],top;
}mp[M];
bool check()
{
	for(int i=1;i<n;i++)
		if(mp[i].num!=mp[i+1].num)
			return false;
	return true;
}
int js,Ans=INF;
void dfs(int x,int js)
{
	if(x>m) return;
	if(js>Ans) return;
	if(check()) 
	{
		Ans=min(Ans,js);
		return;
	}
	for(int i=sz[x].l;i<=sz[x].r;i++)
		mp[i].las[++mp[i].top]=mp[i].num,mp[i].num=sz[x].x;
	dfs(x+1,js+1);
	for(int i=sz[x].l;i<=sz[x].r;i++)
		mp[i].num=mp[i].las[mp[i].top],mp[i].top--;
	dfs(x+1,js);
	return;
}
		
signed main()
{
	freopen("number.in","r",stdin);
	freopen("number.out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<=n;i++)
			mp[i].num=i;
	for(int i=1;i<=m;i++)
		sz[i].l=read(),sz[i].r=read(),sz[i].x=read();
	if(m>=1000) 
	{
		printf("-1
");
		return 0;
	}
	dfs(1,0);
	if(Ans==0) printf("-1
");
	else printf("%lld
",Ans);
	return 0;
}
		

sum

Solution

考试的时候只想到了 (n^3) 的暴力,现在优化到了 (n^2) ,但是不会做到 (nlog n) .

Code

/*
* @Author: smyslenny
* @Date:    2021.08.
* @Title:   
* @Main idea:
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <queue>
#include <vector>

#define ll long long
#define INF 0x3f3f3f3f
#define orz cout<<"LKP AK IOI
"
#define MAX(a,b) (a)>(b)?(a):(b)
#define MIN(a,b) (a)>(b)?(a):(b)

using namespace std;
const int mod=998244353;
const int M=1e3+5;
int f[M];
int read()
{
	int x=0,y=1;
	char c=getchar();
	while(c<'0' || c>'9') {if(c=='-') y=0;c=getchar();}
	while(c>='0' && c<='9') { x=x*10+(c^48);c=getchar();}
	return y?x:-x;
}
int n;
struct ed{
	int u,v,net;
}edge[M<<1];
struct node{
	int u,v;
}bian[M];
int head[M],num;
void addedge(int u,int v)
{
	edge[++num].u=u;
	edge[num].v=v;
	edge[num].net=head[u];
	head[u]=num;
}
int dfn[M],js,id[M],low[M];
void dfs(int u,int fa)
{
	dfn[u]=++js;
	f[u]=fa;
	for(int i=head[u];i;i=edge[i].net)
	{
		int v=edge[i].v;
		if(v==fa) continue;
		dfs(v,u);
	}
	low[u]=js;
}
int Ans,fg[M];
int main()
{
	n=read();
	for(int i=1;i<n;i++)
	{
		int u=read(),v=read();
		bian[i].u=u,bian[i].v=v;
		addedge(u,v);
		addedge(v,u);
	}
	dfs(1,0);
	for(int i=1;i<n;i++)
	{
		int u=bian[i].u,v=bian[i].v;
		if(f[u]==v) swap(u,v);
		for(int j=dfn[v];j<=low[v];j++) fg[j]=1;
		for(int k=1;k<=n;k++)
		{
			int x=k;int id_x=dfn[x],id_i=dfn[k];
			while(x<=n)
			{
				id_x=dfn[x];
				if(fg[id_x]==fg[id_i]) Ans++,x++;
				else break;
			}
		}
		for(int j=dfn[v];j<=low[v];j++) fg[j]=0;
	}
	printf("%d
",Ans);
	return 0;
}
				
本欲起身离红尘,奈何影子落人间。
原文地址:https://www.cnblogs.com/jcgf/p/15245342.html