唔……突然发现最早打的两场(打的最烂的两场)没有写记录……(太烂所以不忍记录了吗。。。

  还是把搞出来了的两道题记录一下吧= =勉强算弥补一下缺憾……

Round0 A

  要求问(1,2)->(n-1,m)  &  (2,1)->(n,m-1)的不相交路径条数,蒟蒻当时只想到了$N^3$的DP……即枚举当前的总步数,以及两个人分别横向走了几步。

  其实正解是(也只能是?)$O(N^2)$的!

  ans=calc{(1,2)->(n-1,m)}*calc{(2,1)->(n,m-1)} - calc{(1,2)->(n,m-1)}*calc{(2,1)->(n-1,m)}

  后面减去的那是啥呢?是两个人走到对方的目的地的总方案数……也就是两人路径交叉的方案数!将交叉的后半段交换一下,与两人走到各自的目的地,且路径发生交叉的方案一一对应!

  (还是容斥原理?)

  我比较傻逼,边界情况没有处理全2333……比如(n-1,m)和(n,m-1)走不到啊什么的……

 1 //Round0 A
 2 #include<vector>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<iostream>
 7 #include<algorithm>
 8 #define rep(i,n) for(int i=0;i<n;++i)
 9 #define F(i,j,n) for(int i=j;i<=n;++i)
10 #define D(i,j,n) for(int i=j;i>=n;--i)
11 using namespace std;
12 typedef long long LL;
13 inline int getint(){
14     int r=1,v=0; char ch=getchar();
15     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
16     for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
17     return r*v;
18 }
19 const int N=2010,mod=1e9+7;
20 /*******************template********************/
21 int n,m,a[N][N];
22 int f[N][N];
23 char s[N];
24 
25 LL calc(int x1,int y1,int x2,int y2){
26     memset(f,0,sizeof f);
27     f[x1][y1]=1;
28     F(i,x1,x2) F(j,y1,y2){
29         if (a[i-1][j]) (f[i][j]+=f[i-1][j])%=mod;
30         if (a[i][j-1]) (f[i][j]+=f[i][j-1])%=mod;
31     }
32     return f[x2][y2];
33 }
34 int main(){
35 #ifndef ONLINE_JUDGE
36     freopen("A.in","r",stdin);
37     freopen("A.out","w",stdout);
38 #endif 
39     n=getint(); m=getint();
40 
41     F(i,1,n){
42         scanf("%s",s+1);
43         F(j,1,m) a[i][j]=s[j]=='0';
44     }
45 //    printf("%lld %lld %lld %lld\n",calc(1,2,n-1,m),calc(2,1,n,m-1),calc(1,2,n,m-1),calc(2,1,n-1,m));
46     if (a[1][2] && a[2][1] && a[n-1][m] && a[n][m-1])
47         printf("%lld\n",(calc(1,2,n-1,m)*calc(2,1,n,m-1)%mod-calc(1,2,n,m-1)*calc(2,1,n-1,m)%mod+mod)%mod);
48     else puts("0");
49     return 0;
50 }
View Code

相关文章: