zoukankan      html  css  js  c++  java
  • 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;
    }
    				
    
    本欲起身离红尘,奈何影子落人间。
  • 相关阅读:
    JavaScript ---Function
    win7(x64)安装scrapy框架
    [转]mysql性能优化-慢查询分析、优化索引和配置
    [原创]win7环境下搭建eclipse+python+django开发环境
    [原创]Python/Django使用富文本编辑器XHeditor上传本地图片
    Ubuntu下mysql使用
    [整理] mysql操作
    [原创]Sql2008 使用TVP批量插入数据
    一个js获取数组下标的函数
    深入理解js的prototype以及prototype的一些应用
  • 原文地址:https://www.cnblogs.com/jcgf/p/15245342.html
Copyright © 2011-2022 走看看