【BZOJ】【3907】网格
组合数学/python
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)有多少种走法。

Input
输入文件中仅有一行,包含两个整数n和m,表示城市街区的规模。
Output
输出文件中仅有一个整数和一个换行/回车符,表示不同的方案总数。
Sample Input
Sample Output
HINT
Source
题面很容易想到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,或者哪位路过的神犇指点我一下……
啊哩怎么跟我当初抄的代码不太一样= =?
/**************************************************************
Problem: 3907
User: Tunix
Language: Python
Result: Accepted
Time:1184 ms
Memory:79228 kb
****************************************************************/ def C(n,m):
return fact[n]/fact[m]/fact[n-m];
f=raw_input().split(" ");
n=int(f[]);
m=int(f[]);
tot=max(n,m)*;
fact=[];
for i in range(,tot+):
fact.append(fact[-]*i);
c=n-m;
ans=C(tot-c,tot/)-C(tot-c,tot/+);
print ans;
UPD:(2015年4月19日 20:21:03)
Orz ykz神犇,提供了他的题解&高精C++代码:
我们假设0表示向右走,1表示向上走,那么很显然问题可以转化为:给你n个0和m个1,求出满足某个条件的01串的个数,这个条件是——对于任意一个子串s[1…i],0的个数不小于1的个数。我们可以用补集转化的方法,所有的01串的个数为$\binom{n+m}{m}$,然后我们再考虑不合法的01串个数。我们假定现在有一个01串,它的0和1的个数分别是n和m,第一次出现不满足条件的位置是i。即s[1…i]当中,0的个数=1的个数-1,并且s[i]=1。我们把s[1…i]的所有0变成1,1变成0,这样,我们得到的新的01串,这个串当中,0和1的个数分别为n+1,m-1。我们发现,这个转化是一一对应的,也就是说,每一个不合法的01串,都对应了一个唯一的一个n+1,m-1的01串;而这个n+1,m-1的01串也正好和唯一的这个不合法串对应,满足充要性。于是我们得到了不合法的01串的个数就是$\binom{n+m}{m-1}$。然后就可以出解啦,为了避免除以0(因为有m-1)我们这么搞:$$ans=\binom{n+m}{m}-\binom{n+m}{n+1} ( \binom{n+m}{m-1}=\binom{n+m}{n+1})$$
/**************************************************************
Problem: 3907
User: Tunix
Language: C++
Result: Accepted
Time:84 ms
Memory:944 kb
****************************************************************/ #include<cstdio>
#include<cstring> typedef long long LL; const int N=;
const LL mod=; int tot=,x[N],p[N],v[N]={};
LL a[],b[]; LL pow(LL x,int p) {
LL t=;for (;p;p>>=,x*=x) if (p&) t*=x;return t;
} void mul(LL a[],LL y) {
LL x=,&l=a[];
for (int i=;i<=l;i++) {
a[i]=a[i]*y+x;
x=a[i]/mod;
a[i]%=mod;
}
while (x) a[++l]=x%mod,x/=mod;
} void dec(LL a[],LL b[]) {
LL &l=a[];
for (int i=;i<=l;i++) {
if (a[i]<b[i]) a[i+]--,a[i]+=mod;
a[i]-=b[i];
}
while (!a[l]) l--;
} void getc(LL a[],int n,int m) {
memset(x,,sizeof x);
for (int i=;i<=n;i++) x[i]++;
for (int i=;i<=m;i++) x[i]--;
for (int i=;i<=n-m;i++) x[i]--;
for (int i=n;i>=;i--)
if (!v[i]) mul(a,pow(i,x[i]));
else x[v[i]]+=x[i],x[i/v[i]]+=x[i];
} void print(LL a[]) {
int l=a[];
printf("%lld",a[l]);
for (int i=l-;i>=;i--) printf("%08lld",a[i]);
printf("\n");
} int main() {
int n,m;
scanf("%d%d",&n,&m);
for (int i=;i<=n+m;i++) {
if (!v[i]) p[++tot]=i;
for (int j=,k;j<=tot,(k=p[j]*i)<=n+m;j++) {
v[k]=p[j];
if (i%p[j]==) break;
}
}
a[]=a[]=b[]=b[]=;
getc(a,n+m,n);
getc(b,n+m,n+);
dec(a,b);
print(a);
return ;
}
【BZOJ】【3907】网格的更多相关文章
- bzoj 3907: 网格 组合数学
3907: 网格 Time Limit: 1 Sec Memory Limit: 256 MBSubmit: 13 Solved: 7[Submit][Status][Discuss] Descr ...
- BZOJ 3907: 网格( 组合数 + 高精度 )
(0,0)->(n,m)方案数为C(n,n+m), 然后减去不合法的方案. 作(n,m)关于y=x+1的对称点(m-1,n+1), 则(0,0)->(m-1,n+1)的任意一条路径都对应( ...
- BZOJ 3907: 网格 [Catalan数 高精度]
3907: 网格 Time Limit: 1 Sec Memory Limit: 256 MBSubmit: 402 Solved: 180[Submit][Status][Discuss] De ...
- BZOJ 3907: 网格
Description 求不跨过直线 \(y=x\) ,到达 \((n,m)\) 的方案数. Sol 组合数学+高精度. 这个推导过程跟 \(Catalan\) 数是一样的. 答案就是 \(C^{n+ ...
- bzoj 3907 网格 bzoj2822 [AHOI2012]树屋阶梯——卡特兰数(阶乘高精度模板)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3907 https://www.lydsy.com/JudgeOnline/problem.p ...
- BZOJ 3907: 网格【组合数学】
Description 某城市的街道呈网格状,左下角坐标为A(0, 0),右上角坐标为B(n, m),其中n >= m.现在从A(0, 0)点出发,只能沿着街道向正右方或者正上方行走,且不能经过 ...
- 【BZOJ 3907】网格 组合数学
大家说他是卡特兰数,其实也不为过,一开始只是用卡特兰数来推这道题,一直没有怼出来,后来发现其实卡特兰数只不过是一种组合数学,我们可以退一步直接用组合数学来解决,这道题运用组合数的思想主要用到补集与几何 ...
- 【BZOJ 3907】网格(Catalan数)
题目链接 这个题推导公式跟\(Catalan\)数是一样的,可得解为\(C_{n+m}^n-C_{n+m}^{n+1}\) 然后套组合数公式\(C_n^m=\frac{n!}{m!(n-m)!}\) ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
随机推荐
- c#中winform的MVP模式的简单实现
MVP模式是类似于MVC模式的一种设计模式,最近在做项目学习过程中遇到,弄了很久终于有一些眉目,这是学习过程中的一些笔记.MVP指的是实体对象Model.视图Viw和业务处理Presenter.MVP ...
- [leetcode]_Minimum Depth of Binary Tree
第五道树题,10分钟之内一遍AC.做树题越来越有feel~ 题目:求一棵树从root结点到叶子结点的最短路径. 思路:仍然是递归.如果一个结点的左右子树任意一边为Null,该子树的minDepth应为 ...
- php对数组排序的例子
分享一个php数组排序的例子,介绍了和php,有关的知识.技巧.经验,和一些php源码等. <?php class='pingjiaF' frameborder='0' src='http:// ...
- 新浪微博登录界面上下拉伸图片--第三方开源--PullToZoomListViewEx(二)
这是PullZoomView在ScrollView实现,Android PullZoomView在ScrollView的实现是:PullToZoomScrollViewEx 下载地址:https:// ...
- 区间 (vijos 1439) 题解
[问题描述] 现给定n个闭区间[ai,bi],1<=i<=n.这些区间的并可以表示为一些不相交的闭区间的并.你的任务就是在这些表示方式中找出包含最少区间的方案.你的输出应该按照区间的升序排 ...
- MapReduce shuffle阶段详解
在Mapreduce中,Shuffle过程是Mapreduce的核心,它分布在Mapreduce的map阶段和reduce阶段,共可分为6个详细的阶段: 1).Collect阶段:将MapTask的结 ...
- ASP.NET Core文章汇总
现有Asp.Net Core 文章资料,2016 3-20月汇总如下 ASP.NET Core 1.0 与 .NET Core 1.0 基础概述 http://www.cnblogs.com/Irvi ...
- “Guess the number” game
项目描述:https://class.coursera.org/interactivepython-004/human_grading/view/courses/972072/assessments/ ...
- golang实现ping命令
// Copyright 2009 The Go Authors. All rights reserved.// Use of this source code is governed by a B ...
- Go语言工程结构
Go是一门推崇软件工程理念的编程语言. Go的代码必须放在GOPATH目录下,它应该包含三个子目录: src:用于以代码包的形式组织并保存Go源码文件.应该分为三类:库源码文件.命令源码文件.测试源码 ...