【Contest Hunter【弱省胡策】Round #0-Flower Dance】组合数学+DP

题目链接:

http://ch.ezoj.tk/contest/%E3%80%90%E5%BC%B1%E7%9C%81%E8%83%A1%E7%AD%96%E3%80%91Round%20%230/Flower%20Dance

 

题意:

在一个n*m的地图上,两个人同时从左上角走到右下角,其中有一些格子是障碍,不能走。

并且,两个人走的路径不能相交。

求总方案数。

 

题解:

昨天晚上做这道题一点靠谱的思路都没有。就是不相交路线那里被弄死了。。

后来听了讲解才发现。。代码如此简单!

就是要开动脑筋啊!智商啊!!!

 

对于两条不相交的路径,那么第一条路径一定是从(1,2)出发,到达(n-1,m);

第二条路径一定是从(2,1)出发,到达(n,m-1);

所以对于一对相交的路径,一定可以从最后一个交点开始按互相交换路径,变为:

第一条路径一定从(1,2)出发,到达(n,m-1);

第二条路径一定从(2,1)出发,到达(n-1,m);

所以,总方案数= 从(1,2)出发到(n-1,m)的方案数 * 从(2,1)出发到达(n,m-1)的方案数 - 

从(1,2)出发到达(n,m-1)的方案数 * 从(2,1)出发到达(n-1,m)的方案数。

DP求解即可。

 

代码如下:

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<vector>
 6 using namespace std;
 7 typedef long long LL;
 8 
 9 const int N=2010,Mod=1000000007;
10 int n,m;
11 char s[N][N];
12 int a[N][N],b[N][N];
13 
14 int main()
15 {
16     scanf("%d%d",&n,&m);
17     for(int i=1;i<=n;i++)
18     {
19         scanf("%s",s[i]+1);
20     }
21     memset(a,0,sizeof(a));
22     memset(b,0,sizeof(b));
23     a[1][1]=b[1][1]=1;
24     for(int i=1;i<=n;i++)
25         for(int j=1;j<=m;j++)
26             if(s[i][j]!='1')
27             {
28                 if(i!=1)  
29                     a[i][j]=(a[i-1][j]+a[i][j-1])%Mod;
30                 if(j!=1)
31                     b[i][j]=(b[i-1][j]+b[i][j-1])%Mod;
32             }
33     LL x=a[n][m-1],y=b[n-1][m],xx=a[n-1][m],yy=b[n][m-1];
34     printf("%lld\n",((x*y)%Mod - (xx*yy)%Mod + Mod)%Mod);
35     return 0;
36 }
View Code

 

posted @ 2015-08-28 08:03  拦路雨偏似雪花  阅读(365)  评论(1编辑  收藏  举报