算法12.从暴力递归到动态规划5

这篇具有很好参考价值的文章主要介绍了算法12.从暴力递归到动态规划5。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

算法|12.从暴力递归到动态规划5

1.机器人行进问题

题意:假设有排成一行的N个位置记为1~N,N一定大于或等于2
开始时机器人在其中的M位置上(M一定是1~N中的一个)
如果机器人来到1位置,那么下一步只能往右来到2位置;
如果机器人来到N位置,那么下一步只能往左来到N-1位置;
如果机器人来到中间位置,那么下一步可以往左走或者往右走;
规定机器人必须走K步,最终能来到P位置(P也是1~N中的一个)的方法有多少种
给定四个参数 N、M、K、P,返回方法数

解题思路:

  • 本题有对应的业务场景,但是我感觉解题其实是从左向右的尝试模型
  • 可变参数有两个当前决策的位置以及剩余的步数
  • 子过程情况讨论的时候分为3种,开头位置,结束位置及普遍位置;rest=0时分为两种情况要么为0要么为1

核心代码:

递归代码:

public static int ways(int N, int start, int aim, int K) {
    if (N < 2 || start < 1 || start > N || aim < 1 || aim > N || K < 1) {
        return -1;
    }
    return process(start, K, aim, N);
}
public static int process(int index, int rest, int aim, int N) {
    if (rest == 0) {
        return index == aim ? 1 : 0;
    }
    if (index == 1) {
        return process(2, rest - 1, aim, N);
    }
    if (index == N) {
        return process(N - 1, rest - 1, aim, N);
    }
    return process(index - 1, rest - 1, aim, N) + process(index + 1, rest - 1, aim, N);
}

dp代码:

public static int dp(int N, int start, int aim, int K) {
    if (N < 2 || start < 1 || start > N || aim < 1 || aim > N || K < 1) {
        return -1;
    }
    int[][] dp = new int[N + 1][K + 1];
    dp[aim][0] = 1;
    for (int rest = 1; rest <= K; rest++) {
        dp[1][rest] = dp[2][rest - 1];
        for (int cur = 2; cur < N; cur++) {
            dp[cur][rest] = dp[cur - 1][rest - 1] + dp[cur + 1][rest - 1];
        }
        dp[N][rest] = dp[N - 1][rest - 1];
    }
    return dp[start][K];
}

测试代码:

public static void main(String[] args) {
    System.out.println(ways(5, 2, 4, 6));
    System.out.println(dp(5, 2, 4, 6));
}

测试结果:假设有排成一行的n个位置记为1~n,n一定大于或等于2,算法,算法,动态规划,java

2.象棋跳马问题

题意:想象一个象棋的棋盘,然后把整个棋盘放入第一象限,棋盘的最左下角是(0,0)位置,那么整个棋盘就是横坐标上9条线、纵坐标上10条线的区域
给你三个 参数 x,y,k
返回“马”从(0,0)位置出发,必须走k步
最后落在(x,y)上的方法数有多少种?

解题思路:

  • 本题有对应的业务场景,但是我感觉解题其实是从左向右的尝试模型
  • 可变参数有三个,当前决策的位置(横纵)以及剩余的步数
  • 子过程情况讨论的时候分为8种,马字;rest=0时分为两种情况要么为0要么为1

核心代码:

递归代码:

public static int jump(int a, int b, int k) {
    return process(0, 0, k, a, b);
}

public static int process(int x, int y, int rest, int a, int b) {
    if (x < 0 || x > 9 || y < 0 || y > 8) {
        return 0;
    }
    if (rest == 0) {
        return (x == a && y == b) ? 1 : 0;
    }
    int ways = process(x + 2, y + 1, rest - 1, a, b);
    ways += process(x + 1, y + 2, rest - 1, a, b);
    ways += process(x - 1, y + 2, rest - 1, a, b);
    ways += process(x - 2, y + 1, rest - 1, a, b);
    ways += process(x - 2, y - 1, rest - 1, a, b);
    ways += process(x - 1, y - 2, rest - 1, a, b);
    ways += process(x + 1, y - 2, rest - 1, a, b);
    ways += process(x + 2, y - 1, rest - 1, a, b);
    return ways;
}

dp代码:

public static int dp(int a, int b, int k) {
    int[][][] dp = new int[10][9][k + 1];
    dp[a][b][0] = 1;
    for (int rest = 1; rest <= k; rest++) {
        for (int x = 0; x < 10; x++) {
            for (int y = 0; y < 9; y++) {
                int ways = pick(dp, x + 2, y + 1, rest - 1);
                ways += pick(dp, x + 1, y + 2, rest - 1);
                ways += pick(dp, x - 1, y + 2, rest - 1);
                ways += pick(dp, x - 2, y + 1, rest - 1);
                ways += pick(dp, x - 2, y - 1, rest - 1);
                ways += pick(dp, x - 1, y - 2, rest - 1);
                ways += pick(dp, x + 1, y - 2, rest - 1);
                ways += pick(dp, x + 2, y - 1, rest - 1);
                dp[x][y][rest] = ways;
            }
        }
    }
    return dp[0][0][k];
}

public static int pick(int[][][] dp, int x, int y, int rest) {
    if (x < 0 || x > 9 || y < 0 || y > 8) {
        return 0;
    }
    return dp[x][y][rest];
}

测试代码:

public static void main(String[] args) {
    int x = 7;
    int y = 7;
    int step = 10;
    System.out.println(jump(x, y, step));

    System.out.println(dp(x, y, step));
}

测试结果:假设有排成一行的n个位置记为1~n,n一定大于或等于2,算法,算法,动态规划,java

3.N皇后问题

题意:N皇后问题是指在N*N的棋盘上要摆N个皇后,
要求任何两个皇后不同行、不同列, 也不在同一条斜线上
给定一个整数n,返回n皇后的摆法有多少种。n=1,返回1
n=2或3,2皇后和3皇后问题无论怎么摆都不行,返回0
n=8,返回92

解题思路:

  • …没有好办法,感觉目前只掌握暴力尝试吧

核心代码:

public static int num1(int n) {
    if (n < 1) {
        return 0;
    }
    int[] record = new int[n];
    return process1(0, record, n);
}

// 当前来到i行,一共是0~N-1行
// 在i行上放皇后,所有列都尝试
// 必须要保证跟之前所有的皇后不打架
// int[] record record[x] = y 之前的第x行的皇后,放在了y列上
// 返回:不关心i以上发生了什么,i.... 后续有多少合法的方法数
public static int process1(int i, int[] record, int n) {
    if (i == n) {
        return 1;
    }
    int res = 0;
    // i行的皇后,放哪一列呢?j列,
    for (int j = 0; j < n; j++) {
        if (isValid(record, i, j)) {
            record[i] = j;
            res += process1(i + 1, record, n);
        }
    }
    return res;
}

public static boolean isValid(int[] record, int i, int j) {
    // 0..i-1
    for (int k = 0; k < i; k++) {
        if (j == record[k] || Math.abs(record[k] - j) == Math.abs(i - k)) {
            return false;
        }
    }
    return true;
}

4.喝咖啡(放弃)

题意:给定一个数组arr,arr[i]代表第i号咖啡机泡一杯咖啡的时间
给定一个正数N,表示N个人等着咖啡机泡咖啡,每台咖啡机只能轮流泡咖啡
只有一台咖啡机,一次只能洗一个杯子,时间耗费a,洗完才能洗下一杯
每个咖啡杯也可以自己挥发干净,时间耗费b,咖啡杯可以并行挥发
假设所有人拿到咖啡之后立刻喝干净,
返回从开始等到所有咖啡机变干净的最短时间
三个参数:int[] arr、int N,int a、int b

解题思路:

核心代码:

测试代码:

测试结果:

业务限制尝试模型总结

改写Dp:

  • 分析清楚业务中的参数,确定范围
  • 套用其他三种尝试模型

例题总结:文章来源地址https://www.toymoban.com/news/detail-831020.html

  • 机器人行进问题——1,7,中间,rest为0,两个可变参数
  • 象棋跳马问题——三个可变参数,走马的八种情况;参数的范围和方向
  • N皇后问题——目前只掌握题意和递归
  • 喝咖啡——放弃…

到了这里,关于算法12.从暴力递归到动态规划5的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 暴力递归到动态规划(三)

    ⭐️ 前言 ⭐️ 本篇文章是从暴力递归到动态规划的第三章。 🍉 欢迎点赞 👍 收藏 ⭐ 留言评论 📝 私信必回哟 😁 🍉 博主将持续更新学习记录收获,友友们有任何问题可以在评论区留言 🍉 博客中涉及源码及博主日常练习代码均已上传GitHub 题目: 给定一个二维数组mat

    2024年02月09日
    浏览(38)
  • 暴力递归到动态规划(四)

    ⭐️ 前言 ⭐️ 本篇文章是从暴力递归到动态规划篇目的最后一篇文章,包含了几道题目还有最终的大总结,相信这篇文章能让各位读者对动态规划有更深一步的了解。 🍉 欢迎点赞 👍 收藏 ⭐ 留言评论 📝 私信必回哟 😁 🍉 博主将持续更新学习记录收获,友友们有任何问

    2024年02月08日
    浏览(42)
  • 左程云 Java 笔记--暴力递归--动态规划

    暴力递归就是尝试 1,把问题转化为规模缩小了的同类问题的子问题 2,有明确的不需要继续进行递归的条件(base case) 3,有当得到了子问题的结果之后的决策过程, 4,不记录每一个子问题的解 打印n层汉诺塔从最左边移动到最右边的全部过程 打印一个字符串的全部子序列,包

    2023年04月08日
    浏览(48)
  • 一篇文章带你搞懂动态规划(由暴力递归到动态规划)

    ”动态规划“ 的过程相当于 记忆化搜索 , 即在普通 递归 的过程中用二维数组进行记忆化存储一些状态结果, 从而避免重复的计算(剪枝)。 举一个简单的例子:在 递归法 求解 斐波那契 数列的过程中, 就进行了多次的 重复计算 , 而动态规划相当于是对已经计算的状态

    2024年02月20日
    浏览(54)
  • 题解 | #上台阶#C++暴力动态规划解法,非递归

    25届想找实习求看看简历 英伟达笔试 Nvidia24秋招 英伟达嵌入式软件工程师笔试 9-26 2022-08-17-nvidia实习 我发现算法岗也不很难进啊(深度学习) 我发现算法岗也不很难进啊(深度学习) 顺丰科技 1.30校招实习招聘信息汇总 2024春招汇总 『 哨哥的校园招聘周报 』02/05 - 02/18 深圳银河创

    2024年02月21日
    浏览(37)
  • 爬楼梯问题-从暴力递归到动态规划(java)

    一个总共N 阶的楼梯(N 0) 每次只能上一阶或者两阶。问总共有多少种爬楼方式。 示例1: N = 1, 一步上去了,返回1. 示例2: N = 2时。 可以第一次上一阶,再上一阶,这是一种方式, 也可以一次直接上两阶,这也是一种方式, 返回 2; 示例3: N = 3: 可以选择, 1 1 1, 1

    2024年02月10日
    浏览(36)
  • 【LeetCode:72. 编辑距离 | 暴力递归=>记忆化搜索=>动态规划 】

    🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,CSDN-Java领域新星创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文

    2024年02月06日
    浏览(51)
  • 【LeetCode:64. 最小路径和 | 暴力递归=>记忆化搜索=>动态规划 】

    🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,CSDN-Java领域新星创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文

    2024年02月05日
    浏览(44)
  • 零钱兑换,凑零钱问题,从暴力递归到动态规划(java)

    322 零钱兑换 - 可以打开链接测试 给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。 计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。 你可以认为每种硬币的数量是无限的。 示例 1:

    2024年02月07日
    浏览(37)
  • 【LeetCode: 44. 通配符匹配 | 暴力递归=>记忆化搜索=>动态规划 】

    🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,CSDN-Java领域优质创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文

    2024年02月06日
    浏览(72)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包