zoukankan      html  css  js  c++  java
  • YCH的模拟赛 T1

    括号序列问题,往往就是把左括号看成+1,右括号看成-1,我们只需要保证任意一个前缀大于等于0,且总和为0,就代表是个合法括号序列了。

    (f[i][j])表示当前到第(i)个字符,现在的前缀和(j)。那么分三种情况考虑。

    若第(i+1)个字符是左括号,则能转移到(f[i+1][j+1])

    若第(i+1)个字符是右括号,则能转移到(f[i+1][j-1])

    若第(i+1)个字符是问号,则能转移到(f[i+1][j-1])(f[i+1][j+1])

    最终(f[n][0])就是方案总数啦。

    时间复杂度为(O(n^2))

    优化:

    二维数组一定会炸。。。。

    那就。。。循环队列!

    我们发现每次到新的一个 $i $,它只和 (i-1) 有关,所以 (i-1) 用过一次就可以销毁了,不然也是占空间

    可以像这样&1​来实现循环利用

    f[i & 1][0]=0
    

    STD

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=1e9+7;
    int n;
    int f[3005][3005];
    char c[3005];
    
    int main()
    {
    	scanf("%d",&n);
    	scanf("%s",c+1);
    	f[0][0]=1;
    	for(int i=1;i<=n;i++)
    	{
    		if(c[i]=='Y')
    		{
    			for(int j=1;j<=i;j++)
    			{
    				f[i][j]=f[i-1][j-1];
    			}
    		}
    		if(c[i]=='H')
    		{
    			for(int j=0;j<i;j++)
    			{
    				f[i][j]=f[i-1][j+1];
    			}
    		}
    		if(c[i]=='C')
    		{
    			f[i][0]=f[i-1][1];
    			for(int j=1;j<i;j++)
    			{
    				f[i][j]=(f[i-1][j+1]+f[i-1][j-1])%mod;
    			}
    			f[i][i]=f[i-1][i-1];
    		}
    	}
    	cout<<f[n][0]%mod;
    }
    
    
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=1e9+7;
    int n;
    int f[3][10005];
    char c[10005];
    
    int main()
    {
    	freopen("data10.in","r",stdin);
    	freopen("data10.out","w",stdout);
    	scanf("%d",&n);
    	scanf("%s",c+1);
    	memset(f,0,sizeof(f));
    	f[0][0]=1;
    	for(int i=1;i<=n;i++)
    	{
    		if(c[i]=='Y')
    		{
    			f[i&1][0]=0;
    			for(int j=1;j<=i;j++)
    			{
    				f[i&1][j]=f[(i-1)&1][j-1];
    			}
    		}
    		if(c[i]=='H')
    		{
    			f[i&1][i]=0;
    			for(int j=0;j<i;j++)
    			{
    				f[i&1][j]=f[(i-1)&1][j+1];
    			}
    		}
    		if(c[i]=='C')
    		{
    			f[i&1][0]=f[(i-1)&1][1];
    			for(int j=1;j<i;j++)
    			{
    				f[i&1][j]=(f[(i-1)&1][j+1]+f[(i-1)&1][j-1])%mod;
    			}
    			f[i&1][i]=f[(i-1)&1][i-1];
    		}
    	}
    	cout<<f[n&1][0]%mod;
    }
    
  • 相关阅读:
    【转载】为什么我的网站加www是打不开的呢
    【转载】IIS网站配置不带www域名直接跳转带www的域名
    【转载】IIS网站如何同时解析带www和不带www的域名
    【转载】C#中将字符串分割成字符数组
    Android面试,简要介绍一下asynctask和handler的优缺点
    Android面试题(2)
    Android面试题(1)
    Android -- 与WEB交互在同一个会话Session中通信
    25匹马的角逐
    Android -- 检测耳机插入状态
  • 原文地址:https://www.cnblogs.com/lcezych/p/13266794.html
Copyright © 2011-2022 走看看