3907: 网格

Time Limit: 1 Sec  Memory Limit: 256 MB
Submit: 162  Solved: 76
[Submit][Status][Discuss]

Description

某 城市的街道呈网格状,左下角坐标为A(0, 0),右上角坐标为B(n, m),其中n >= m。现在从A(0, 0)点出发,只能沿着街道向正右方或者正上方行走,且不能经过图示中直线左上方的点,即任何途径的点(x, y)都要满足x >= y,请问在这些前提下,到达B(n, m)有多少种走法。
【BZOJ】【3907】网格

Input

输入文件中仅有一行,包含两个整数n和m,表示城市街区的规模。

Output

输出文件中仅有一个整数和一个换行/回车符,表示不同的方案总数。

Sample Input

6 6

Sample Output

132

HINT

100%的数据中,1 <= m <= n <= 5 000


Source

[Submit][Status][Discuss]

  题面很容易想到Catalan数……但是5000的范围实在是有些吃不消……

  题解:http://www.cnblogs.com/mhy12345/p/4343980.html

copy了下代码sorry……  

 

  UPD:(2015-04-02 16:53:03)

  好吧我还是来写一下吧:

    我们求不越过$y=x$这条线的方案数不是很好求,那么我们就利用补集转化的思想来求。首先所有方案的总数是$C(n+m,n)$,其中所有不合法的方案,即中途跨过了$ y=x $这条线的路径,我们都可以将跨越点之后的路径翻折一下,得到一条从(1,1)到(m,n)的路线,也就是说,所有不合法的方案数之和即为C(n+m,n-1)。容我三思QAQ,或者哪位路过的神犇指点我一下……

    啊哩怎么跟我当初抄的代码不太一样= =?

 1 /**************************************************************
 2     Problem: 3907
 3     User: Tunix
 4     Language: Python
 5     Result: Accepted
 6     Time:1184 ms
 7     Memory:79228 kb
 8 ****************************************************************/
 9 
10 def C(n,m):
11     return fact[n]/fact[m]/fact[n-m];
12 f=raw_input().split(" ");
13 n=int(f[0]);
14 m=int(f[1]);
15 tot=max(n,m)*2;
16 fact=[1];
17 for i in range(1,tot+1):
18     fact.append(fact[-1]*i);
19 c=n-m;
20 ans=C(tot-c,tot/2)-C(tot-c,tot/2+1);
21 print ans;
View Code

相关文章: