这题第一想法是矩阵,不过范围太大了,然后就没有思路了。。
之后看到群里的解法,行和列可以分着走,两者是互不影响的,这样就把二维转换成了一维,直接dp求出就可以了。
然后再组合相乘一下。
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define N 1010 12 #define LL __int64 13 #define INF 0xfffffff 14 #define mod 9999991 15 const double eps = 1e-8; 16 const double pi = acos(-1.0); 17 const double inf = ~0u>>2; 18 LL dp1[N][N],dp2[N][N]; 19 LL o[2][N]; 20 LL c[N][N]; 21 void init() 22 { 23 c[0][0] = 1; 24 for(int i = 1;i < 1010;i++) 25 { 26 c[i][0] = c[i][i] = 1; 27 for(int j = 1; j < i;j++) 28 { 29 c[i][j] = c[i-1][j] + c[i-1][j-1]; 30 if(c[i][j] >= mod) 31 c[i][j] -= mod; 32 } 33 } 34 } 35 int main() 36 { 37 int n,m,t,k,x,y; 38 int i,j; 39 int kk = 0; 40 init(); 41 cin>>t; 42 while(t--) 43 { 44 memset(dp1,0,sizeof(dp1)); 45 memset(dp2,0,sizeof(dp2)); 46 memset(o,0,sizeof(o)); 47 scanf("%d%d%d%d%d",&n,&m,&k,&x,&y); 48 dp1[0][x] = 1;o[0][0]+=1; 49 dp2[0][y] = 1;o[1][0]+=1; 50 for(i = 1;i <=k ;i++) 51 for(j = 1; j <=n ;j++) 52 { 53 if(j>1) dp1[i][j]=(dp1[i][j]+dp1[i-1][j-2])%mod; 54 dp1[i][j]+=dp1[i-1][j-1];dp1[i][j]%=mod; 55 dp1[i][j]+=dp1[i-1][j+1];dp1[i][j]%=mod; 56 dp1[i][j]+=dp1[i-1][j+2];dp1[i][j]%=mod; 57 o[0][i]+=dp1[i][j]; 58 o[0][i]%=mod; 59 } 60 for(i = 1; i <=k ;i++) 61 for(j = 1; j <= m ;j++) 62 { 63 if(j>1) dp2[i][j]+=dp2[i-1][j-2];dp2[i][j]%=mod; 64 dp2[i][j]+=dp2[i-1][j-1];dp2[i][j]%=mod; 65 dp2[i][j]+=dp2[i-1][j+1];dp2[i][j]%=mod; 66 dp2[i][j]+=dp2[i-1][j+2];dp2[i][j]%=mod; 67 o[1][i]+=dp2[i][j]; 68 o[1][i]%=mod; 69 } 70 71 LL ans=0; 72 for(i = 0; i <= k; i++) 73 { 74 ans =(ans+c[k][i]*o[0][i]%mod*o[1][k-i]%mod)%mod; 75 } 76 printf("Case #%d: ",++kk); 77 cout<<ans<<endl; 78 } 79 return 0; 80 }