【codevs2516】【BZOJ2461】符环,DP

来源:互联网 发布:淘宝少女前线初始号 编辑:程序博客网 时间:2024/05/18 21:12

传送门1
传送门2
写在前面:爆〇
思路:
(下面的组合数只是快速处理出全是’S’的情况,加快程序而已= =)
刚开始有5维DP的想法(怎么总比std多一维)但显然这是错误的,即使能做也会MLE
感觉状态有点难想,f[now][x][y][z]指对位置now,左边有x个’(‘,右边有y个’)’,右边有z个’(‘(且它们都未在各自的范围内匹配),所以我们就比较容易想出它的转移了
当操作为’S’时,我们可以选’(‘,那么x+1,z+1(不要管y);
也可以选’)’,但要求x>0,不然就非法了,那么x-1,z-1或y+1(由z是否>0决定)
当操作为’D’,我们可以选’()’,那么x+1,z-1或y+1;
也可以选’)(‘,那么x-1,z+1
最后判断条件要求右边没有’(‘未匹配,并且左边’(‘与右边’)’相等,即(x==y) and (z==0)
注意:多组数据初始化,注意上述转移的条件判断

#include<bits/stdc++.h>#define LL long longusing namespace std;int t,len;char s[60];bool flag[52][52][52][52];LL f[52][52][52][52],C[52][52];bool pd(char ch[]){    for (int i=0;i<len;i++)    if (ch[i]!='S') return 0;    return 1;}LL dfs(int now,int x,int y,int z){    if (now==len) return (x==y)&&(!z);    if (flag[now][x][y][z]) return f[now][x][y][z];    if (s[now]=='S')    {        f[now][x][y][z]+=dfs(now+1,x+1,y,z+1);        if (x)        {            if (z) f[now][x][y][z]+=dfs(now+1,x-1,y,z-1);            else f[now][x][y][z]+=dfs(now+1,x-1,y+1,z);        }    }    else    {        if (z) f[now][x][y][z]+=dfs(now+1,x+1,y,z-1);        else f[now][x][y][z]+=dfs(now+1,x+1,y+1,z);        if (x) f[now][x][y][z]+=dfs(now+1,x-1,y,z+1);    }    flag[now][x][y][z]=1;    return f[now][x][y][z];}main(){    C[0][0]=1;    for (int i=1;i<=50;i++)    for (int j=0;j<=i;j++)    if (j)    C[i][j]=C[i-1][j]+C[i-1][j-1];    else C[i][j]=C[i-1][j];    scanf("%d",&t);    while (t--)    {        scanf("%s",s);        len=strlen(s);        if (pd(s)) {printf("%lld\n",(len&1)?0:C[len][len/2]/(LL)(len/2+1));continue;}        memset(flag,0,sizeof(flag));        memset(f,0,sizeof(f));        printf("%lld\n",dfs(0,0,0,0));    }}
0 0
原创粉丝点击