JZOJ.3431【GDOI2014模拟】网格 解题报告
2016-06-12 12:33
811 查看
网格
题目描述
某城市的街道呈网格状,左下角坐标为A(0,0),右上角坐标为B(n,m),其中n>=m。现在从A(0,0)点出发,只能沿着街道向正右方或者正上方行走,且不能经过图示中直线左上方的点,即任何途径的点(x,y)都要满足x>=y,请问在这些前提下,到达B(n,m)有多少种走法。样例输入
6 3样例输出
132数据范围
100%的数据中,1 <= m <= n <= 5000题解
关于这种不能穿过某条直线的网格行走问题,先讲一下怎么做。我们知道,答案就等于走到点(n,m)的所有路径数量减去穿过这条直线的路径数量。
我们还知道由点(0,0)走到点(n,m)的路径数为Cn(m)n+m。
所以我们现在只需求得穿过这条直线的路径数量就可以知道答案了。
对于一个如下的网格,有这样的一条违法路径穿过了y=x这条直线。
易得,不能穿过y=x这条直线就等于不能碰到y=x+1,所以我们找到y=x+1这条直线(图中为棕色直线),并将原路径沿这条直线对称过去(除了最下面的一段,图中为橙色),可以得到下图
像这样,路径中点A(n,m)会对称到点B(m-1,n+1),并且从原点走到对称点B(m-1,n+1)的一条路径都可以对称回来,并对应着一条从原点走到终点A(n,m)且穿过y=x直线的路径。
所以穿过直线y=x的路径数就对于从原点走到对称点的路径数。
走到对称点B(m-1,n+1)的路径数SB=Cm−1n+1+m−1=Cm−1n+m
走到原终点A(n,m)的路径数SA=Cmn+m
则
Ans=SA-SB
=Cmn+m-Cm−1n+m
=(n+m)!m!∗n! − (n+m)!(m−1)!∗(n+1)!=(n+m)!∗(n+1)m!∗(n+1)! − (n+m)!∗mm!∗(n+1)!
=(n+m)!∗(n+1−m)m!∗(n+1)!
再约一下分,得
Ans=(n+2)∗(n+3)∗(n+4)∗......∗(n+m)∗(n+1−m)m!
分数线上面的部分我们可以用高精度乘法将积算出来。
那分母怎么处理呢?
我们看到数据范围,惊奇的发现m<=5000,于是我们可以打一个单精度除法除m次。
因为直接打会超时,所以打高精度时要压位。
Code(Pascal)
const mo=100000000000000; var lj,dt:array[0..30000] of int64; n,m,j,i,l:longint; k,o:int64; procedure cs(o:int64); var i,j,l:longint; hhh:int64; begin hhh:=0; for i:=1 to lj[0] do begin dt[i]:=lj[i]*o+hhh; hhh:=dt[i] div mo; dt[i]:=dt[i] mod mo; end; dt[0]:=lj[0]; while hhh>0 do begin inc(dt[0]); dt[dt[0]]:=hhh mod mo; hhh:=hhh div mo; end; for i:=0 to dt[0] do lj[i]:=dt[i]; end; procedure cd(o:int64); var i,j,l:longint; hhh:int64; begin for i:=lj[0] downto 1 do begin dt[i]:=(lj[i]+hhh) div o; hhh:=(lj[i]-dt[i]*o+hhh)*mo; end; dt[0]:=lj[0]; while (dt[dt[0]]=0) and (dt[0]>0) do dec(dt[0]); for i:=lj[0] downto dt[0] do lj[i]:=0; for i:=0 to dt[0] do lj[i]:=dt[i]; end; begin readln(n,m); lj[0]:=1; lj[1]:=1; for i:=n+2 to n+m do cs(i); cs(n+1-m); for i:=1 to m do cd(i); write(lj[lj[0]]); for i:=lj[0]-1 downto 1 do begin k:=lj[i]; o:=0; while k>0 do begin inc(o); k:=k div 10; end; for l:=1 to 14-o do write(0); write(lj[i]); end; end.
相关文章推荐
- unity知识总结
- vc精确控制时间
- NC开发中 一些bug总结
- [朝花夕拾]基于C#的模拟仿真平台设计(部分)及服务器异步通信代码
- 生成debug.keystire
- Chart.js 学习笔记
- 冒泡排序 查找排序
- Powershell日常AD管理-2
- iOS编程(3)NavigationController
- 模式识别(Pattern Recognition)学习笔记(二十)--BP算法
- [jvm解析系列][十]类加载器和双亲委派模型,你真的了解ClassLoader吗?
- 第十六周阅读程序-7
- hadoop单机环境搭建
- C# StructLayout(LayoutKind.Sequential)]
- 第十五周的学习进度条
- 《数学之美》 吴军
- 计数排序
- DIV重叠 CSS让DIV层叠 两个DIV或多个DIV顺序重叠加
- leetcode Single Number III
- 【Get深一度】高斯白噪声之——散粒噪声(shot noise )