算法思想之分治法

一、背景

在算法中我们会遇到一些题描述如下:第一种:一个机器人一次走1<=k<=m,那么请问走到第n台阶有多少中走法。第二种:一个机器人只能向上或者向右走1<=k<=m,求走到第(p,q)的位置总共有多少种走法。

二、解决

1. 分析

这类问题都是斐波拉切函数的衍生问题,这里给出模型图和具体步骤。

2. 模型图

3. 解决步骤

类似于这列问题都是按照分治思想来解决,具体如下:

# 可走的步数为1<=k<=m
# 假定k为3步,那么可走的步数为1,2,3
# 第一阶 可走步数1  总共1中方法
# 第二阶 第一阶台阶 + 可走步数1  可走步数2 总共2种方法
# 第三阶 第二阶台阶 + 可走步数1 * 2  第一阶台阶+可走步数2  可走步数3 总共4种方法
# 第四阶台阶 第一阶台阶+可走步数3 第二台阶+可走步数2 第三阶台阶+可走步数1 总共7中方法
# 第五阶依次类推 

由此可见我们只需要初始化三个数字,对着三个数字进行打表计算,在O(n)的时间复杂度内我们就可以完成这个过程。

4. 代码

4.1 跳台阶

#include <iostream>

using namespace std;

void pathStep(int m);

int main() {
    int m;
    cin >> m;
    pathStep(m);
    return 1;
}

void pathStep(int m) {
   // 跳台阶
int a = 1, b = 2; for (int i = 2; i < m; i += 2) { //因为a,b每次运算都做了运算因此步长取2 a = b + a; b = a + b; } cout << b; }

 4.2 机器人路径

#include <iostream>

using namespace std;

void robots(int m, int n);

int main() {
// robots路径  方格路径
    int m, n;
    cin >> m >> n;
    robots(m, n);
    return 1;
}

void robots(int m, int n) {
    int path[m][n];
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            if (i == 0 || j == 0) {
                path[i][j] = 1; // 便捷路径为1
            } else {
                path[i][j] = path[i - 1][j] + path[i][j - 1];
            }
        }
    }
    cout << path[m - 1][n - 1];
}

猜你喜欢

转载自www.cnblogs.com/future-dream/p/12890917.html