1155. 擲骰子的N種方法


1155. 擲骰子的N種方法

題目描述

這里有 d 個一樣的骰子,每個骰子上都有 f 個面,分別標號為 1, 2, ..., f。

我們約定:擲骰子的得到總點數為各骰子面朝上的數字的總和。

如果需要擲出的總點數為 target,請你計算出有多少種不同的組合情況(所有的組合情況總共有 f^d 種),模 10^9 + 7 后返回。

思路分析(二維)

這個題是動態規划問題,參考一篇文章吃透背包問題!(細致引入+解題模板+例題分析+代碼呈現)

的分析思路,首先,這個是一個分組背包問題,然后又是組合問題。分組背包的特點是在每個數的選擇上都有好幾個選擇,可以把每個篩子當成普通背包的重量,不過這個重量是看可以變得。可以用三個循環,前兩個循環按照題目按照0/1背包、完全背包和組合背包的要求寫,第三個循環時選擇重量(在本題中就是骰子的點數)。對於本題。最外面循環是骰子的個數d,然后 中間一層是target,由於這個每個骰子是不可重復用的,因此taget循環用倒序(如果是二維dp那么正序也可以),然后最后一層便是點數的循環f。本題中用dp[i] [j]表示用前i個骰子得到目標和j的組合數目,那么有dp[i] [j]+=dp[i] [k],k>=1&&k<=j

代碼實現

class Solution {
public:
    
    int numRollsToTarget(int d, int f, int target) {
        const int mod=1000000007;
        vector<vector<int>>dp(d+1,vector<int>(target+1,0));
        //初始化
        dp[0][0]=1;
        //對於骰子遍歷
        for(int i=1;i<=d;i++)
        {
            //對於target的遍歷
            for(int j=target;j>=1;j--)
            {
                //對於骰子的遍歷,細節1:j>=k
                for(int k=1;k<=f&&j>=k;k++)
                {
                    dp[i][j]+=dp[i-1][j-k];
                    dp[i][j]%=mod;
                }
            }
        }

        return dp[d][target];
    }
};

思路分析(一維優化)

對於一維優化,設定dp[j]為目標和為j的組合數目。相比於二維,需要注意的一個細節便是骰子都必須用上,因此如果用假如兩個骰子那么得到的最小數便是2,那么就需要dp[j],j<i需要設置為0(二維dp不用擔心),另外一個細節是骰子不能搖出來0(所以不能用dp[j]直接加,需要從0開始加)。

class Solution {
public:
    
    int numRollsToTarget(int d, int f, int target) {
        const int mod=1000000007;
        vector<int>dp(target+1,0);
        dp[0]=1;
        for(int i=1;i<=d;i++)
        {
			//細節1:倒序,這樣加的是上一層的
            for(int j=target;j>=i;j--)
            {
                //細節2:只加當點數為1—k的
                int sum=0;
                for(int k=1;k<=f&&j>=k;k++)
                {
                    sum+=dp[j-k];
                    sum%=mod;
                }
                dp[j]=sum;
            }
            //細節3:小於篩子個數的設置為0
            for(int j=0;j<i;j++)
                dp[j]=0; 
        }
        return dp[target];
       
    }
};


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM