【LeetCode:1155. 掷骰子等于目标和的方法数 | 递归->缓存->dp】

|-----------|
| 🚀 算法题 🚀 |

🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀
🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨
🌲 作者简介:硕风和炜,CSDN-Java领域新星创作者🏆,保研|国家奖学金|高中学习JAVA|大学完善JAVA开发技术栈|面试刷题|面经八股文|经验分享|好用的网站工具分享💎💎💎
🌲 恭喜你发现一枚宝藏博主,赶快收入囊中吧🌻
🌲 人生如棋,我愿为卒,行动虽慢,可谁曾见我后退一步?🎯🎯

|-----------|
| 🚀 算法题 🚀 |

🍔 目录

    • [🚩 题目链接](#🚩 题目链接)
    • [⛲ 题目描述](#⛲ 题目描述)
    • [🌟 求解思路&实现代码&运行结果](#🌟 求解思路&实现代码&运行结果)
      • [⚡ 缓存 | dp](#⚡ 缓存 | dp)
        • [🥦 求解思路](#🥦 求解思路)
        • [🥦 实现代码 - 记忆化缓存](#🥦 实现代码 - 记忆化缓存)
        • [🥦 运行结果](#🥦 运行结果)
        • [🥦 实现代码 - dp](#🥦 实现代码 - dp)
        • [🥦 运行结果](#🥦 运行结果)
    • [💬 共勉](#💬 共勉)

🚩 题目链接

⛲ 题目描述

这里有 n 个一样的骰子,每个骰子上都有 k 个面,分别标号为 1 到 k 。

给定三个整数 n , k 和 target ,返回可能的方式(从总共 kn 种方式中)滚动骰子的数量,使正面朝上的数字之和等于 target 。

答案可能很大,你需要对 109 + 7 取模 。

示例 1:

输入:n = 1, k = 6, target = 3

输出:1

解释:你扔一个有 6 个面的骰子。

得到 3 的和只有一种方法。

示例 2:

输入:n = 2, k = 6, target = 7

输出:6

解释:你扔两个骰子,每个骰子有 6 个面。

得到 7 的和有 6 种方法:1+6 2+5 3+4 4+3 5+2 6+1。

示例 3:

输入:n = 30, k = 30, target = 500

输出:222616187

解释:返回的结果必须是对 109 + 7 取模。

提示:

1 <= n, k <= 30

1 <= target <= 1000

🌟 求解思路&实现代码&运行结果


⚡ 缓存 | dp

🥦 求解思路
  1. 通过理解题目的意思我们知道,该题目让我们求解的是如何使用n个筛子,每个筛子都有k面,最后可以得到target数的总方案数。
  2. 我们可以拆分问题的求解规模,比如,我们先使用第一个筛子,筛子可以摇到1-k个数字(此时我们直接遍历),此时target就会减去筛子对应摇到的数。接下来,我们继续重复这个过程,该过程就是使用n-1个筛子,筛子可以摇到1-k个数字(此时我们直接遍历),此时target也依然减去筛子对应摇到的数。最后求得满足target的总的方案数目。
  3. 因为递归超时了,代码也比较简单,大家自行实现,我们直接进入缓存。
  4. 具体求解的过程步骤请看下面代码。
🥦 实现代码 - 记忆化缓存
java 复制代码
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
class Solution {
    
    final static int mod=(int)(1e9+7);
    int n=0;
    int k=0;
    int target=0;
    int[][] dp;

    public int numRollsToTarget(int n, int k, int target) {
        if(target<n||target>n*k){
            return 0; 
        }
        this.n=n;
        this.k=k;
        this.target=target;
        this.dp=new int[n+1][n*k+1];
        for(int i=0;i<=n;i++){
            Arrays.fill(dp[i],-1);
        }
        return process(0,0);
    }

    public int process(int i,int sum){
        if(sum>target) return 0;
        if(i>=n){
            return dp[i][sum]=sum==target?1:0;
        }
        if(dp[i][sum]!=-1) return dp[i][sum];
        int res=0;
        for(int j=1;j<=k;j++){
            res=(res+process(i+1,sum+j))%mod;
        }
        return dp[i][sum]=res%mod;
    }
}
🥦 运行结果
🥦 实现代码 - dp
java 复制代码
class Solution {
    
    final static int mod=(int)(1e9+7);
    int n=0;
    int k=0;
    int target=0;
    int[][] dp;

    public int numRollsToTarget(int n, int k, int target) {
        if(target<n||target>n*k){
            return 0; 
        }
        this.n=n;
        this.k=k;
        this.target=target;
        this.dp=new int[n+1][n*k+1];
        for(int i=0;i<=n;i++){
            dp[i][target]=1;
        }
        for(int i=n-1;i>=0;i--){
            for(int sum=target;sum>=0;sum--){
                int res=0;
                for(int j=1;j<=k&&sum+j<=n*k;j++){
                    res=(res+dp[i+1][sum+j])%mod;
                }
                dp[i][sum]=res%mod;
            }
        }
        return dp[0][0];
    }
}
🥦 运行结果

💬 共勉

|----------------------------------|
| 最后,我想和大家分享一句一直激励我的座右铭,希望可以与大家共勉! |

相关推荐
Swift社区6 小时前
从 JDK 1.8 切换到 JDK 21 时遇到 NoProviderFoundException 该如何解决?
java·开发语言
DKPT7 小时前
JVM中如何调优新生代和老生代?
java·jvm·笔记·学习·spring
phltxy7 小时前
JVM——Java虚拟机学习
java·jvm·学习
seabirdssss8 小时前
使用Spring Boot DevTools快速重启功能
java·spring boot·后端
喂完待续9 小时前
【序列晋升】29 Spring Cloud Task 微服务架构下的轻量级任务调度框架
java·spring·spring cloud·云原生·架构·big data·序列晋升
benben0449 小时前
ReAct模式解读
java·ai
蒹葭玉树9 小时前
【C++上岸】C++常见面试题目--算法篇(第二十期)
c++·算法·面试
轮到我狗叫了9 小时前
牛客.小红的子串牛客.kotori和抽卡牛客.循环汉诺塔牛客.ruby和薯条
java·开发语言·算法
Volunteer Technology10 小时前
三高项目-缓存设计
java·spring·缓存·高并发·高可用·高数据量