lightOJ 1299 Fantasy Cricket

题目链接:http://lightoj.com/volume_showproblem.php?problem=1299

题意:给出一个字符串S只含有UDE三种字 母。设字符串长度为n,S[1,n]。求n的全排列中有多少个满足下列条件(设某个全排列为 A[1,n]):S[A[i]]为U则A[i]<i;S[A[i]]为D则A[i]>i;S[A[i]]为E则A[i]=i。换句话说就是原 来串中的字母D都要前移,U都要后移,E不变。

思路:显然,对于E我们直接忽视掉即可。设f[i][j]表示前i个位置中还有j个字母未安排位置,那么:

(1)当前字母为D,则f[i][j]=f[i-1][j]*j(在前面找一个位置将这个D放下),f[i][j-1]=f[i][j]*j*j(在前面找一个没放的U放在这个位置,然后再将这个位置的D放下);

(2)当前字母为D,f[i][j+1]=f[i-1][j](又多了一个没放的),f[i][j]=f[i-1][j]*j(前面找一个没放的放在这里,然后这个位置的U还是没放)。

 

char s[N];

i64 n,f[N][N];



void up(i64 &x,i64 y)

{

    x=(x+y%mod)%mod;

}





int cal()

{

    clr(f,0); f[0][0]=1;

    int i,j;

    FOR1(i,n)

    {

        if(s[i]=='D')

        {

            FOR0(j,i)

            {

                up(f[i][j],f[i-1][j]*j);

                if(j) up(f[i][j-1],f[i-1][j]*j*j);

            }

        }

        else

        {

            FOR0(j,i)

            {

                up(f[i][j+1],f[i-1][j]);

                up(f[i][j],f[i-1][j]*j);

            }

        }

    }

    return f[n][0];

}





int main()

{

    int num=0;

    rush()

    {

        RD(s+1);

        n=0;

        int i,L=strlen(s+1);

        FOR1(i,L) if(s[i]!='E') s[++n]=s[i];

        printf("Case %d: ",++num);

        PR(cal());

    }

}

 

 

 

你可能感兴趣的:(ant)