[SCOI2010]字符串

 

思路:

设1为向(1,1)方向走,0为向(1,-1)方向走。那么题意可转化为从(0,0)走到(n+m,n-m)且不能跨过y=0的方案数。总方案数C(n+m,n),然后要减去不合法的即线路通过y=-1的。将线路与y=-1交点的左边沿着y=-1做对称操作,则最后等价于从(0,-2)走到(n+m,n-m)的方案数。因为从(0,-2)

走到(n+m,n-m)需要向上走n-m+2次,一共要走n+m次。设向上向下各走x,y,那么x+y=n+m,x-y=n-m+2得到x=n+1,y=m-1,所以不合法的方案为C(n+m,m-1)。

[SCOI2010]字符串

 

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int mod=20100403;
const int N=1001;
int n,m,ans,f[2][N][N];
void dp(){
//    f[n+m][n][m]=1;
    int now=0;
    f[now][n][m]=1;
    for(int i=n+m-1;~i;i--){
        now^=1;
        for(int j=0;j<=n;j++){
            for(int k=0;k<=m;k++){
                if(j>k&&k<m) f[now][j][k]+=f[now^1][j][k+1];
                if(j<n) f[now][j][k]+=f[now^1][j+1][k];
                if(f[now][j][k]>=mod) f[now][j][k]-=mod;
            }
        }
    }
    printf("%d\n",f[now][0][0]);
}
int main(){
    freopen("string.in","r",stdin);
    freopen("string.out","w",stdout);
    cin>>n>>m;
    if(n<m){puts("0");return 0;}
    dp();
    return 0;
}
10分dp

相关文章: