Codeforces 367E

来源:互联网 发布:禁毒网络知识竞赛 编辑:程序博客网 时间:2024/06/16 10:28

dp[i][j][k]表示前i个数,出现j个左边界k个右边界情况总数
1. 左边界
2. 右边界
3. 左边界和右边界
4. 什么都不是

#include<cstdio>#include<iostream>#include<cstring>using namespace std;typedef __int64 LL;const int mod=1e9+7;LL jie[400];void init(){    jie[0]=1;    int n=350;    for(int i=1;i<=n;i++){        jie[i]=(LL)jie[i-1]*i%mod;    }}void fun(LL x,LL &y){    y+=x;    if(y>=mod)y-=mod;}LL dp[2][400][400];int main(){    #ifdef DouBi    freopen("in.cpp","r",stdin);    #endif // DouBi    init();    int n,m,id;    while(scanf("%d%d%d",&n,&m,&id)!=EOF){        if(n>m){            printf("0\n");continue;        }        memset(dp,0,sizeof(dp));        dp[0][0][0]=1;        for(int i=1;i<=m;i++){            int x=i%2;            if(i<id)dp[x][0][0]=1;            else dp[x][0][0]=0;            for(int j=1;j<=min(n,i);j++){                LL y=0;                if(i!=id){                    fun(dp[x^1][j][0],y);                    fun(dp[x^1][j-1][0],y);                }                else {                    fun(dp[x^1][j-1][0],y);                }                dp[x][j][0]=y;                for(int j1=1;j1<=j;j1++){                    y=0;                    if(i!=id){                        fun(dp[x^1][j][j1],y);                        fun(dp[x^1][j-1][j1],y);                        fun(dp[x^1][j][j1-1],y);                        fun(dp[x^1][j-1][j1-1],y);                    }                    else {                        fun(dp[x^1][j-1][j1],y);                        fun(dp[x^1][j-1][j1-1],y);                    }                    dp[x][j][j1]=y;                }            }            //printf("%d:%d\n",i,dp[x][n][n]);            //if(i>=id)fun(dp[x][n][n],ans);        }        int ans=(LL)dp[m%2][n][n]*jie[n]%mod;        //printf("%djie\n",jie[n]);        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击