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

简介: 【每日一题Day357】LC1155掷骰子等于目标和的方法数 | dp

掷骰子等于目标和的方法数【LC1155】

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

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

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


第一眼很像背包

记忆化
  • 思路

image.png

class Solution {
    public static final int MOD = (int)(1e9 + 7);
    int[][] dp;
    int k;
    public int numRollsToTarget(int n, int k, int target) {
        // 选择n个数,值为1-k,和为target的方案数
        if (n * k < target) return 0;     
        this.k = k;        
        this.dp = new int[n + 1][target + 1];       
        for (int i = 1; i <= n; i++){
            Arrays.fill(dp[i], -1);
        }
        dp[0][0] = 1;
        return dfs(n, target);
    }
    public int dfs(int n, int target){
        if (dp[n][target] != -1) return dp[n][target];
        int res = 0;
        for (int i = 1; i <= Math.min(target, k); i++){            
            res = (res + dfs(n - 1, target - i)) % MOD;         
        }
        dp[n][target] = res;
        return res;
    }
}

image.png

  • 优化:每个数至少取1, 因此可以将target减少n,每个数的范围减小1
递推
  • 实现
class Solution {
    public static final int MOD = (int)(1e9 + 7);
    public int numRollsToTarget(int n, int k, int target) {
        // 选择n个数,值为1-k,和为target的方案数
        if (n * k < target) return 0;            
        int[][] dp = new int[n + 1][target + 1];       
        dp[0][0] = 1;
        for (int i = 1; i <= n; i++){
            for (int j = 1; j <= Math.min(k, target); j++){
                for (int v = j; v <= target; v++){
                    dp[i][v] = (dp[i][v] + dp[i - 1][v - j]) % MOD;
                }
            }
        }
        return dp[n][target];
    }
}


目录
相关文章
|
8月前
|
算法 测试技术
枚举(蓝桥练习)(反倍数、特别数的和、找到最多的数、小蓝的漆房、小蓝和小桥的挑战)
枚举(蓝桥练习)(反倍数、特别数的和、找到最多的数、小蓝的漆房、小蓝和小桥的挑战)
|
8月前
【每日一题Day289】LC1749任意子数组和的绝对值的最大值 | dp
【每日一题Day289】LC1749任意子数组和的绝对值的最大值 | dp
53 0
|
8月前
【每日一题Day264】LC931下降路径最小和 | dp
【每日一题Day264】LC931下降路径最小和 | dp
56 0
|
8月前
|
索引
【每日一题Day183】LC1187使数组严格递增 | dp
【每日一题Day183】LC1187使数组严格递增 | dp
44 0
|
8月前
【每日一题Day211】LC1079活字印刷 | 回溯 计数dp
【每日一题Day211】LC1079活字印刷 | 回溯 计数dp
63 0
|
8月前
【每日一题Day221】LC2455可被三整除的偶数的平均值 | 模拟
【每日一题Day221】LC2455可被三整除的偶数的平均值 | 模拟
57 0
|
8月前
【每日一题Day278】LC2500删除每行中的最大值 | 排序+模拟
【每日一题Day278】LC2500删除每行中的最大值 | 排序+模拟
53 0
|
8月前
【每日一题Day291】LC1289下降路径最小和 II | dp
【每日一题Day291】LC1289下降路径最小和 II | dp
43 0
|
8月前
【每日一题Day358】LC2698求一个整数的惩罚数 | 递归
【每日一题Day358】LC2698求一个整数的惩罚数 | 递归
60 0

热门文章

最新文章