LeetCode 0935.骑士拨号器:动态规划(DP)

news2024/12/26 23:52:22

【LetMeFly】935.骑士拨号器:动态规划(DP)

力扣题目链接:https://leetcode.cn/problems/knight-dialer/

象棋骑士有一个独特的移动方式,它可以垂直移动两个方格,水平移动一个方格,或者水平移动两个方格,垂直移动一个方格(两者都形成一个 的形状)。

象棋骑士可能的移动方式如下图所示:

我们有一个象棋骑士和一个电话垫,如下所示,骑士只能站在一个数字单元格上(即蓝色单元格)。

给定一个整数 n,返回我们可以拨多少个长度为 n 的不同电话号码。

你可以将骑士放置在任何数字单元格上,然后你应该执行 n - 1 次移动来获得长度为 n 的号码。所有的跳跃应该是有效的骑士跳跃。

因为答案可能很大,所以输出答案模 109 + 7.

 

    示例 1:

    输入:n = 1
    输出:10
    解释:我们需要拨一个长度为1的数字,所以把骑士放在10个单元格中的任何一个数字单元格上都能满足条件。
    

    示例 2:

    输入:n = 2
    输出:20
    解释:我们可以拨打的所有有效号码为[04, 06, 16, 18, 27, 29, 34, 38, 40, 43, 49, 60, 61, 67, 72, 76, 81, 83, 92, 94]
    

    示例 3:

    输入:n = 3131
    输出:136006598
    解释:注意取模
    

     

    提示:

    • 1 <= n <= 5000

    解题方法:动态规划

    使用 d p [ i ] dp[i] dp[i]代表当前这一步号码为 i i i时的总方案数,初始值 d p [ 0 ] = d p [ 1 ] = ⋯ = d p [ 9 ] = 0 dp[0] = dp[1] = \cdots = dp[9] = 0 dp[0]=dp[1]==dp[9]=0

    预先打表一个 c a n F r o m canFrom canFrom数组, c a n F r o m [ i ] canFrom[i] canFrom[i]代表能从哪些号码一步到达号码 i i i:

    canFrom = {
        {4, 6},  // 0可以来自4,6
        {6, 8},
        {7, 9},
        {4, 8},
        {3, 9, 0},
        {},
        {1, 7, 0},
        {2, 6},
        {1, 3},
        {2, 4}
    };
    

    之后从第2个号码开始,假设当前号码为 i i i,则有状态转移方程:

    d p [ i ] = s u m ( d p [ f r o m ] ) , f r o m ∈ c a n F r o m [ i ] dp[i] = sum(dp[from]), from \in canFrom[i] dp[i]=sum(dp[from]),fromcanFrom[i]

    • 时间复杂度 O ( n ) O(n) O(n),其中常数比较大,为canFrom数组中的数据量20
    • 空间复杂度 O ( 1 ) O(1) O(1)

    AC代码

    C++
    const vector<vector<int>> canFrom = {
        {4, 6},  // 0可以来自4,6
        {6, 8},
        {7, 9},
        {4, 8},
        {3, 9, 0},
        {},
        {1, 7, 0},
        {2, 6},
        {1, 3},
        {2, 4}
    };
    const int mod = 1e9 + 7;
    
    class Solution {
    public:
        int knightDialer(int n) {
            int last[10], now[10];
            fill(last, last + 10, 1);
            for (int i = 2; i <= n; i++) {
                memset(now, 0, sizeof(now));
                for (int j = 0; j < 10; j++) {
                    for (int from : canFrom[j]) {
                        now[j] = (now[j] + last[from]) % mod;
                    }
                }
                memcpy(last, now, sizeof(now));
            }
            // return accumulate(last, last + 10, 0);  // WA,这里没取模
            int ans = 0;
            for (int i = 0; i < 10; i++) {
                ans = (ans + last[i]) % mod;
            }
            return ans;
        }
    };
    
    Python
    # AC,57.50%,56.76%
    CAN_FROM = [
        [4, 6],
        [6, 8],
        [7, 9],
        [4, 8],
        [3, 9, 0],
        [], 
        [1, 7, 0],
        [2, 6],
        [1, 3],
        [2, 4]
    ]
    MOD = 1_000_000_007
    
    class Solution:
        def knightDialer(self, n: int) -> int:
            last = [1] * 10
            for _ in range(n - 1):
                now = [0] * 10
                for i in range(10):
                    for j in CAN_FROM[i]:
                        now[i] = (now[i] + last[j]) % MOD
                last = now
            return sum(last) % MOD
    
    Java
    import java.util.Arrays;
    
    class Solution {
        private final int[][] canFrom = {
            {4, 6},  // 0可以来自4,6
            {6, 8},
            {7, 9},
            {4, 8},
            {3, 9, 0},
            {},
            {1, 7, 0},
            {2, 6},
            {1, 3},
            {2, 4}
        };
        private final int mod = 1000000007;
    
        public int knightDialer(int n) {
            int[] last = new int[10];
            int[] now = new int[10];
            Arrays.fill(last, 1);
            for (int i = 2; i <= n; i++) {
                for (int j = 0; j < 10; j++) {
                    for (int from : canFrom[j]) {
                        now[j] = (now[j] + last[from]) % mod;
                    }
                }
                last = now;
            }
            int ans = 0;
            for (int i = 0; i < 10; i++) {
                ans = (ans + last[i]) % mod;
            }
            return ans;
        }
    }
    
    Go
    package main
    
    var canFrom = [][]int{
        {4, 6},  // 0可以来自4,6
        {6, 8},
        {7, 9},
        {4, 8},
        {3, 9, 0},
        {},
        {1, 7, 0},
        {2, 6},
        {1, 3},
        {2, 4},
    };
    var mod = 1000000007
    
    func knightDialer(n int) (ans int) {
        last := make([]int, 10)
        for i := range last {
            last[i] = 1
        }
        for i := 2; i <= n; i++ {
            now := make([]int, 10)
            for j := 0; j < 10; j++ {
                for _, from := range canFrom[j] {
                    now[j] = (now[j] + last[from]) % mod
                }
            }
            last = now
        }
        for i := range last {
            ans = (ans + last[i]) % mod;
        }
        return
    }
    

    同步发文于CSDN和我的个人博客,原创不易,转载经作者同意后请附上原文链接哦~

    Tisfy:https://letmefly.blog.csdn.net/article/details/144375933

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2257588.html

    如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

    相关文章

    No.4 笔记 探索网络安全:揭开Web世界的隐秘防线

    在这个数字时代&#xff0c;网络安全无处不在。了解Web安全的基本知识&#xff0c;不仅能保护我们自己&#xff0c;也能帮助我们在技术上更进一步。让我们一起深入探索Web安全的世界&#xff0c;掌握那些必备的安全知识&#xff01; 1. 客户端与WEB应用安全 前端漏洞&#xff1…

    PHP使用local-proxy的一种思路! | 架构师之路(19)

    《架构师之路&#xff1a;架构设计中的100个知识点》 19.脚本语言使用长连接的一种思路 脚本类语言&#xff0c;例如PHP&#xff0c;不能像C/Java那样能搞服务常驻内存&#xff0c;不能搞长连接&#xff1f; 为什么脚本语言要搞长连接&#xff1f; 脚本类语言每次访问后端数据库…

    【51单片机】程序实验1112.外部中断-定时器中断

    主要参考学习资料&#xff1a;B站【普中官方】51单片机手把手教学视频 前置知识&#xff1a;C语言 单片机套装&#xff1a;普中STC51单片机开发板A4标准版套餐7 码字不易&#xff0c;求点赞收藏加关注(•ω•̥) 有问题欢迎评论区讨论~ 目录 程序实验11&12.外部中断-定时器…

    驱动---1.DAC8552实现三角波输出

    最近开始进行新项目的研发&#xff0c;考虑用DAC做一个前级输出&#xff0c;选择了DAC8552这个器件的一个模块&#xff0c;用了野火的指南者做主控&#xff0c;芯片是STM32F103VET6&#xff0c;主频是72MHz。 一、器件手册重要信息提取 1.DAC8552具有十六位的分辨率、双通道输…

    虚幻引擎生存建造系统

    先做一个建造预览模式&#xff0c;按下按键B后进入建造预览模式 首先创建自定义事件Preview Loop 用射线追踪摆放物体预览位置&#xff0c;并做一个预览材质 增强输入设置按键 每帧判断是否进入建造模式 预览模式制作成功&#xff01; 接着做点击左键放置物品&#xff0…

    IP研究 | 大数据洞察黄油小熊的爆火之路

    一只来自泰国的小熊在国内红成了顶流。 今年&#xff0c;黄油小熊以烘焙店“打工人”的超萌形象迅速走红&#xff0c;2个月内火遍中国的社交媒体&#xff0c;泰国门店挤满飘洋过海求合影的中国粉丝&#xff0c;根据数说故事全网大数据洞察&#xff0c;黄油小熊2024年度的线上声…

    深度学习案例:DenseNet + SE-Net

    本文为为&#x1f517;365天深度学习训练营内部文章 原作者&#xff1a;K同学啊 一 回顾DenseNet算法 DenseNet&#xff08;Densely Connected Convolutional Networks&#xff09;是一种深度卷积神经网络架构&#xff0c;提出的核心思想是通过在每一层与前面所有层进行直接连接…

    【java学习笔记】Set接口实现类-LinkedHashSet

    一、LinkedHashSet的全面说明 &#xff08;就是把数组不同位置的链表当成一个节点然后相连&#xff09;

    【大模型系列篇】LLaMA-Factory大模型微调实践 - 从零开始

    前一次我们使用了NVIDIA TensorRT-LLM 大模型推理框架对智谱chatglm3-6b模型格式进行了转换和量化压缩&#xff0c;并成功部署了推理服务&#xff0c;有兴趣的同学可以翻阅《NVIDIA TensorRT-LLM 大模型推理框架实践》&#xff0c;今天我们来实践如何通过LLaMA-Factory对大模型…

    【C++】LeetCode:LCR 078. 合并 K 个升序链表

    题干&#xff1a; 给定一个链表数组&#xff0c;每个链表都已经按升序排列。 请将所有链表合并到一个升序链表中&#xff0c;返回合并后的链表。 解法&#xff1a;优先队列 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *ne…

    数据结构和算法-04二叉树-04

    广度优先的实现力扣中常见的二叉树相关问题及基本解决方案 tips&#xff1a; 在解决问题时&#xff0c;先确保问题能解决&#xff0c;再去考虑效率&#xff0c;这是解题的关键&#xff0c;切不可为追求效率而变成了技巧性解答。 广度优先 广度优先(层序遍历)遍历的方式是按层次…

    DMA代码部分

    第一个程序的接线图 OLED ShowHexNum(2,1,(uint32_t)&ADC1->DR,8); 这样可以看AD的DR寄存器的的地址(固定的)了 可以跑一下然后和手册对比 先查ADC1的地址 再在外设的总表里面, 查一下DR相对于上面地址的偏移量 所以其地址为4001 244C 研究一下外设寄存器的地址是怎么…

    spdlog高性能日志系统

    spdlog高性能日志系统 spdlog 是一个快速、简单、功能丰富的 C 日志库&#xff0c;专为现代 C 开发设计。它支持多种日志后端&#xff08;如控制台、文件、syslog 等&#xff09;&#xff0c;并提供灵活的格式化和线程安全的日志输出。 1. 特点 极高的性能&#xff1a;大量的编…

    FPGA在线升级 -- Multiboot

    简介 本章节主要描述关于如何从Golden Image转换到Multiboot Image程序。 升级方案 Golden Image转换到Multiboot Image的方法主要又两种 1、使用ICAPE2 原语&#xff1b; 2、在XDC文件中加入升级约束命令&#xff1b; 以上两种方案都可以实现在线升级&#xff0c;第一种升级…

    守护进程化

    目录 一、进程组 二、会话 &#xff08;1&#xff09;什么是会话 &#xff08;2&#xff09;如何创建一个会话 三、守护进程 一、进程组 之前我们学习过进程&#xff0c;其实每一个进程除了有一个进程 ID(PID)之外 还属于一个进程组。进程组是一个或者多个进程的集合&…

    QML插件扩展

    https://note.youdao.com/ynoteshare/index.html?id294f86c78fb006f1b1b78cc430a20d74&typenote&_time1706510764806

    RabbitMQ七种工作模式之 RPC通信模式, 发布确认模式

    文章目录 六. RPC(RPC通信模式)客户端服务端 七. Publisher Confirms(发布确认模式)1. Publishing Messages Individually(单独确认)2. Publishing Messages in Batches(批量确认)3. Handling Publisher Confirms Asynchronously(异步确认) 六. RPC(RPC通信模式) 客⼾端发送消息…

    ArcGIS字符串补零与去零

    我们有时候需要 对属性表中字符串的补零与去零操作 我们下面直接视频教学 下面看视频教学 ArcGIS字符串去零与补零 推荐学习 ArcGIS全系列实战视频教程——9个单一课程组合 ArcGIS10.X入门实战视频教程&#xff08;GIS思维&#xff09; ArcGIS之模型构建器&#xff08;Mod…

    前端面试如何出彩

    1、原型链和作用域链说不太清&#xff0c;主要表现在寄生组合继承和extends继承的区别和new做了什么。2、推荐我的两篇文章&#xff1a;若川&#xff1a;面试官问&#xff1a;能否模拟实现JS的new操作符、若川&#xff1a;面试官问&#xff1a;JS的继承 3、数组构造函数上有哪些…

    大模型应用编排工具Dify之构建专属FQA应用

    1.前言 ​ 通过 dify可以基于开源大模型的能力&#xff0c;并结合业务知识库、工具API和自定义代码等构建特定场景、行业的专属大模型应用。本文通过 dify工作室的聊天助手-工作流编排构建了一个基于历史工作日志回答问题的助手&#xff0c;相比原始的大模型答复&#xff0c;通…