【排列组合】给定一个M*N的格子或棋盘,从左下角走到右上角的走法总数(每次只能向右或向上移动一个方格边长的距离)
版权声明:本文为CSDN博主「梵解君」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hadeso/article/details/12622743
--------------------------------------------------------------------------------------------------------------------
解法1:我们可以把棋盘的左下角看做二维坐标的原点(0,0),把棋盘的右上角看做二维坐标(m,n)(坐标系的单位长度为小方格的变长)
用f(i, j)表示移动到坐标f(i, j)的走法总数,其中0=<i, j<=n,设f(m, n)代表从坐标(0,0)到坐标(m,n)的移动方法,
则f(m, n) = f(m-1, n) + f(m, n-1).
于是状态f(i, j)的状态转移方程为:
f(i, j) = f(i-1, j) + f(i, j-1) if i, j>0
f(i, j) = f(i, j-1) if i=0
f(i, j) = f(i-1, j) if j=0
优化的状态f(i, j)的状态转移方程为:

递归结束条件为:f(0,0)=0, f(0,1)=1, f(1,0)=1。这个问题可以在时间O(n^2),空间O(n^2)内求解。
递归解法
//递归解法
int process(int m, int n) {
//永远不可能达到m & n同时为0的条件,除非输入m=n=0
if (m == 0 && n == 0)
return 0;
if (m == 0 || n == 0)
return 1;
return process(m, n - 1) + process(m - 1, n);
}
非递归解法
int processNew(int m,int n){
int **Q=new int*[m+1];
for(int i=0; i<=m; ++i){
Q[i]=new int[n+1]();
}
//初始化
Q[0][0]=0;
for(int j=1; j<=n; ++j)
Q[0][j]=1;
for(int i=1; i<=m; ++i)
Q[i][0]=1;
//迭代计算
for(int i=1; i<=m; ++i){
for(int j=1; j<=n; ++j){
Q[i][j]=Q[i-1][j]+Q[i][j-1];
}
}
int res=Q[m][n];
delete [] Q;
return res;
}
解法2:这个题目其实是一个组合问题。对方向编号,向上是0,向右是1,那么从左下角走到右上角一定要经过M 个1和N个0。这个题目可以转化为从M+N个不同的盒子中挑出M个盒子有多少种方法。答案是C(M+N, M),或者C(M+N, N)的组合数。
【排列组合】给定一个M*N的格子或棋盘,从左下角走到右上角的走法总数(每次只能向右或向上移动一个方格边长的距离)的更多相关文章
- nyoj1076-方案数量 【排列组合 dp】
http://acm.nyist.net/JudgeOnline/problem.php?pid=1076 方案数量 时间限制:1000 ms | 内存限制:65535 KB 难度:2 描述 ...
- 一个n*n 的方格,要从左上角走到右下角,一次只能往右或往下走一步,求算法得出所有走动的方法数。
题目一:一个n*n 的方格,要从左上角走到右下角,一次只能往右或往下走一步,求算法得出所有走动的方法数. 分析:对于第(i,j)个格子,只有向右走一步到达或者向左走一步到达,dp(i,j) = d(i ...
- 给定数组a[1,2,3],用a里面的元素来生成一个长度为5的数组,打印出其排列组合
给定数组a[1,2,3],用a里面的元素来生成一个长度为5的数组,打印出其排列组合 ruby代码: def all_possible_arr arr, length = 5 ret = [] leng ...
- js 排列 组合 的一个简单例子
最近工作项目需要用到js排列组合,于是就写了一个简单的demo. 前几天在网上找到一个写全排列A(n,n)的code感觉还可以,于是贴出来了, 排列的实现方式: 全排列主要用到的是递归和数组的插入 比 ...
- C++写一个排列组合小程序
今天突然想到一个问题,有时候,针对同一个事件有多种反映,特别是游戏AI当中,这种情况下需要采取最适合的方案,哪种方案最适合,可以将每种方案的结果或影响都计算一遍,从而选择最合适的.最基本就是一个排列组 ...
- PHP的排列组合问题 分别从每一个集合中取出一个元素进行组合,问有多少种组合?
首先说明这是一个数学的排列组合问题C(m,n) = m!/(n!*(m-n)!) 比如:有集合('粉色','红色','蓝色','黑色'),('38码','39码','40码'),('大号','中号') ...
- 【原创】开源.NET排列组合组件KwCombinatorics使用(三)——笛卡尔积组合
本博客所有文章分类的总目录:本博客博文总目录-实时更新 本博客其他.NET开源项目文章目录:[目录]本博客其他.NET开源项目文章目录 KwCombinatorics组件文章目录: 1. ...
- 【原创】开源.NET排列组合组件KwCombinatorics使用(二)——排列生成
本博客所有文章分类的总目录:本博客博文总目录-实时更新 本博客其他.NET开源项目文章目录:[目录]本博客其他.NET开源项目文章目录 KwCombinatorics组件文章目录: 1. ...
- 【原创】开源.NET排列组合组件KwCombinatorics使用(一)—组合生成
本博客所有文章分类的总目录:本博客博文总目录-实时更新 本博客其他.NET开源项目文章目录:[目录]本博客其他.NET开源项目文章目录 KwCombinatorics组件文章目录: 1. ...
随机推荐
- 百度富文本编辑器ueditor添加到pom
<!-- 百度富文本编辑start --> <dependency> <groupId>com.baidu</groupId> <artifact ...
- 在 ASP.NET Core 项目中使用 AutoMapper 进行实体映射
一.前言 在实际项目开发过程中,我们使用到的各种 ORM 组件都可以很便捷的将我们获取到的数据绑定到对应的 List<T> 集合中,因为我们最终想要在页面上展示的数据与数据库实体类之间可能 ...
- Go语言操作MySQL
MySQL是常用的关系型数据库,本文介绍了Go语言如何操作MySQL数据库. Go操作MySQL 连接 Go语言中的database/sql包提供了保证SQL或类SQL数据库的泛用接口,并不提供具体的 ...
- Scala 学习笔记之函数(3)
class student{ def sayHello(name: => String){ println(s"Hello, $name, welcome $name") } ...
- spring boot项目下application.properties中使用logging.path和logging.file时的细节
logging.path仅仅用于指定日志输出的目录,且不能指定输出的文件名,且默认名为spring.log 若指定的是相对目录,则会生成在当前总项目的目录下 idea中新建sprnig boot项目 ...
- 02-28 scikit-learn库之线朴素贝叶斯
目录 scikit-learn库之朴素贝叶斯 一.MultinomialNB 1.1 使用场景 1.2 代码 1.3 参数详解 1.4 属性 1.5 方法 二.GaussianNB 三.Bernoul ...
- github基本使用---从零开始
1.使用之前首先得有账号(附链接):https://github.com/ 2.注册帐号之后得有方便上传项目的工具git bash下载安装 https://gitforwindows.org/ 3.启 ...
- 【JZOJ5248】花花的聚会
Description 注意测试数据中道路是 到 的单向道路,与题面恰好相反. Input Output Sample Input 7 7 1 3 1 2 6 7 3 6 3 5 3 4 7 2 3 ...
- 考试题string——线段树。
string[题目描述]给定一个由小写字母组成的字符串 s.有 m 次操作,每次操作给定 3 个参数 l,r,x.如果 x=1,将 s[l]~s[r]升序排序;如果 x=0,将 s[l]~s[r]降序 ...
- python 中的一点新知识
逻辑行与物理行 所谓物理行(Physical Line)是你在编写程序时 你所看到 的内容.所谓逻辑行(Logical Line)是 Python 所看到 的单个语句.Python 会假定每一 物理行 ...