【每日一题】掷骰子等于目标和的方法数

文章目录

Tag

【动态规划】【数组】


题目来源

1155. 掷骰子等于目标和的方法数


题目解读

你手里有 n 个一样的骰子,每个骰子都有 k 个面,分别标号 1n。给定三个整数 nktarget,返回这个 n 个骰子正面朝上的数字组成 target 的所有方案数。答案可能很大,返回对 1 e 9 + 7 1e9+7 1e9+7 取模后的值。


解题思路

方法一:动态规划

我们可以使用动态来解决本题。

状态

f[i][j] 表示使用 i 个骰子且数字和为 j 的方案数。

转移关系

我们可以枚举最后一个骰子的数字,数字的范围在 [1, k],使用 i 个骰子组成的数字和为 j 的方案数为:

f [ i , j ] = ∑ x = 1 k f [ i − 1 ] [ j − k ] f\left[ i,j \right] =\sum_{x=1}^k{f\left[ i-1 \right] \left[ j-k \right]} f[i,j]=x=1∑kf[i−1][j−k]

base case

f[0][0] = 1,计即我们还没有掷骰子,数字之和为 0 时的方案数。

最终返回

最终返回 f[n][target],表示使用 n 个骰子正面朝上的数字组成 target 的所有方案数

实现代码

cpp 复制代码
class Solution {
public:
    int numRollsToTarget(int n, int k, int target) {
        if (target < n || target > n * k) {
            return 0;
        }

        const int MOD = 1e9 + 7;
        vector<vector<int>> f(n+1, vector<int>(target+1));
        f[0][0] = 1;
        for (int i = 1; i <= n; ++i) {
            for (int j = 0; j <= target; ++j) {
                for (int x = 1; x <= k; ++x) {
                    if (j - x >= 0) {
                        f[i][j] = (f[i][j] + f[i-1][j-x]) % MOD;
                    }
                }
            }
        }
        return f[n][target];
    }
};

优化

注意观察状态转移方程,f[i][j] 只会从 f[i-1, ...] 转移过来,因此只需要存储第 i 行和第 i-1 行的值,使用两个一维数组代替二维数组进行转态转移。

cpp 复制代码
class Solution {
public:
    int numRollsToTarget(int n, int k, int target) {
        if (target < n || target > n * k) {
            return 0;
        }

        const int MOD = 1e9 + 7;
        vector<int> f(target + 1);
        f[0] = 1;
        for (int i = 1; i <= n; ++i) {
            vector<int> g(target + 1);
            for (int j = 0; j <= target; ++j) {
                for (int x = 1; x <= k; ++x) {
                    if (j - x >= 0) {
                        g[j] = (g[j] + f[j-x]) % MOD;
                    }
                }
            }
            f = g;
        }
        return f[target];
    }
};

复杂度分析

时间复杂度: O ( n ⋅ k ⋅ t a r g e t ) O(n \cdot k \cdot target) O(n⋅k⋅target)。

空间复杂度: O ( n ⋅ t r a g e t ) O(n \cdot traget) O(n⋅traget),优化后的空间复杂度为 O ( t a r g e t ) O(target) O(target)。


写在最后

如果文章内容有任何错误或者您对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度方法,欢迎评论区交流。

最后,感谢您的阅读,如果感到有所收获的话可以给博主点一个 👍 哦。

相关推荐
鹏大师运维3 小时前
【功能介绍】信创终端系统上各WPS版本的授权差异
linux·wps·授权·麒麟·国产操作系统·1024程序员节·统信uos
亦枫Leonlew4 小时前
微积分复习笔记 Calculus Volume 1 - 4.7 Applied Optimization Problems
笔记·数学·微积分·1024程序员节
小肥象不是小飞象4 小时前
(六千字心得笔记)零基础C语言入门第八课——函数(上)
c语言·开发语言·笔记·1024程序员节
一个通信老学姐13 小时前
专业130+总400+武汉理工大学855信号与系统考研经验电子信息与通信工程,真题,大纲,参考书。
考研·信息与通信·信号处理·1024程序员节
力姆泰克13 小时前
看电动缸是如何提高农机的自动化水平
大数据·运维·服务器·数据库·人工智能·自动化·1024程序员节
力姆泰克13 小时前
力姆泰克电动缸助力农业机械装备,提高农机的自动化水平
大数据·服务器·数据库·人工智能·1024程序员节
程思扬14 小时前
为什么Uptime+Kuma本地部署与远程使用是网站监控新选择?
linux·服务器·网络·经验分享·后端·网络协议·1024程序员节
姜西西_14 小时前
动态规划 之 斐波那契数列模型 算法专题
算法·动态规划
转世成为计算机大神14 小时前
网关 Spring Cloud Gateway
java·网络·spring boot·1024程序员节
paopaokaka_luck14 小时前
基于Spring Boot+Vue的助农销售平台(协同过滤算法、限流算法、支付宝沙盒支付、实时聊天、图形化分析)
java·spring boot·小程序·毕业设计·mybatis·1024程序员节