📜  通过重复掷骰子来计算获得给定总和的方法

📅  最后修改于: 2021-04-27 17:14:23             🧑  作者: Mango

给定一个整数N ,任务是找到通过反复掷骰子来获得总和N的方法的数量。

例子:

递归方法:想法是对骰子的每个可能值进行迭代以获得所需的总和N。步骤如下:

  1. findWays()为总和N的必需答案。
  2. 从掷骰子获得的唯一数字是[1,6] ,每个骰子掷出的概率均相等。
  3. 因此,对于每个状态,都针对先前的(N – i)个状态(其中1≤i≤6 )重复出现。因此,递归关系如下:

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to find the number of ways
// to get the sum N with throw of dice
int findWays(int N)
{
    // Base Case
    if (N == 0) {
        return 1;
    }
 
    // Stores the count of total
    // number of ways to get sum N
    int cnt = 0;
 
    // Recur for all 6 states
    for (int i = 1; i <= 6; i++) {
 
        if (N - i >= 0) {
 
            cnt = cnt
                  + findWays(N - i);
        }
    }
 
    // Return answer
    return cnt;
}
 
// Driver Code
int main()
{
    int N = 4;
 
    // Function call
    cout << findWays(N);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to find the number of ways
// to get the sum N with throw of dice
static int findWays(int N)
{
     
    // Base Case
    if (N == 0)
    {
        return 1;
    }
 
    // Stores the count of total
    // number of ways to get sum N
    int cnt = 0;
 
    // Recur for all 6 states
    for(int i = 1; i <= 6; i++)
    {
        if (N - i >= 0)
        {
            cnt = cnt +
                  findWays(N - i);
        }
    }
 
    // Return answer
    return cnt;
}
 
// Driver Code
public static void main(String[] args)
{
    int N = 4;
 
    // Function call
    System.out.print(findWays(N));
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 program for the above approach
 
# Function to find the number of ways
# to get the sum N with throw of dice
def findWays(N):
     
    # Base case
    if (N == 0):
        return 1
 
    # Stores the count of total
    # number of ways to get sum N
    cnt = 0
 
    # Recur for all 6 states
    for i in range(1, 7):
        if (N - i >= 0):
            cnt = cnt + findWays(N - i)
 
    # Return answer
    return cnt
     
# Driver Code
if __name__ == '__main__':
     
    N = 4
 
    # Function call
    print(findWays(N))
 
# This code is contributed by mohit kumar 29


C#
// C# program for
// the above approach
using System;
class GFG{
 
// Function to find the number of ways
// to get the sum N with throw of dice
static int findWays(int N)
{
  // Base Case
  if (N == 0)
  {
    return 1;
  }
 
  // Stores the count of total
  // number of ways to get sum N
  int cnt = 0;
 
  // Recur for all 6 states
  for(int i = 1; i <= 6; i++)
  {
    if (N - i >= 0)
    {
      cnt = cnt + findWays(N - i);
    }
  }
 
  // Return answer
  return cnt;
}
 
// Driver Code
public static void Main()
{
  int N = 4;
 
  // Function call
  Console.Write(findWays(N));
}
}
 
// This code is contributed by sanjoy_62


C++
// C++ Program for the above approach
 
#include 
using namespace std;
 
// Function to calculate the total
// number of ways to have sum N
int findWays(int N, int dp[])
{
    // Base Case
    if (N == 0) {
        return 1;
    }
 
    // Return already stored result
    if (dp[N] != -1) {
 
        return dp[N];
    }
 
    int cnt = 0;
 
    // Recur for all 6 states
    for (int i = 1; i <= 6; i++) {
 
        if (N - i >= 0) {
            cnt = cnt
                  + findWays(N - i, dp);
        }
    }
 
    // Return the result
    return dp[N] = cnt;
}
 
// Driver Code
int main()
{
    // Given sum N
    int N = 4;
 
    // Initialize the dp array
    int dp[N + 1];
 
    memset(dp, -1, sizeof(dp));
 
    // Function Call
    cout << findWays(N, dp);
 
    return 0;
}


Java
// Java Program for
// the above approach
import java.util.*;
class GFG{
 
// Function to calculate the total
// number of ways to have sum N
static int findWays(int N, int dp[])
{
    // Base Case
    if (N == 0)
    {
        return 1;
    }
 
    // Return already
    // stored result
    if (dp[N] != -1)
    {
        return dp[N];
    }
 
    int cnt = 0;
 
    // Recur for all 6 states
    for (int i = 1; i <= 6; i++)
    {
        if (N - i >= 0)
        {
            cnt = cnt +
                  findWays(N - i, dp);
        }
    }
 
    // Return the result
    return dp[N] = cnt;
}
 
// Driver Code
public static void main(String[] args)
{
    // Given sum N
    int N = 4;
 
    // Initialize the dp array
    int []dp = new int[N + 1];
 
    for (int i = 0; i < dp.length; i++)
        dp[i] = -1;
 
    // Function Call
    System.out.print(findWays(N, dp));
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 Program for the
# above approach
 
# Function to calculate
# the total number of ways
# to have sum N
def findWays(N, dp):
 
    # Base Case
    if (N == 0):
        return 1
    
    # Return already
    # stored result
    if (dp[N] != -1):
        return dp[N]
 
    cnt = 0
 
    # Recur for all 6 states
    for i in range (1, 7):
        if (N - i >= 0):
            cnt = (cnt +
                   findWays(N - i, dp))
 
    # Return the result
    dp[N] = cnt
    return dp[N]
 
# Driver Code
if __name__ == "__main__":
 
    # Given sum N
    N = 4
 
    # Initialize the dp array
    dp = [-1] * (N + 1)
 
    # Function Call
    print(findWays(N, dp))
 
# This code is contributed by Chitranayal


C#
// C# Program for
// the above approach
using System;
class GFG{
 
// Function to calculate the total
// number of ways to have sum N
static int findWays(int N, int []dp)
{
  // Base Case
  if (N == 0)
  {
    return 1;
  }
 
  // Return already stored result
  if (dp[N] != -1)
  {
    return dp[N];
  }
 
  int cnt = 0;
 
  // Recur for all 6 states
  for (int i = 1; i <= 6; i++)
  {
    if (N - i >= 0)
    {
      cnt = cnt + findWays(N - i, dp);
    }
  }
 
  // Return the result
  return dp[N] = cnt;
}
 
// Driver Code
public static void Main(String[] args)
{
  // Given sum N
  int N = 4;
 
  // Initialize the dp array
  int []dp = new int[N + 1];
 
  for (int i = 0; i < dp.Length; i++)
    dp[i] = -1;
 
  // Function Call
  Console.Write(findWays(N, dp));
}
}
  
// This code is contributed by Rajput-Ji


C++
// C++ Program for the above approach
 
#include 
using namespace std;
 
// Function to calculate the total
// number of ways to have sum N
void findWays(int N)
{
    // Initialize dp array
    int dp[N + 1];
 
    dp[0] = 1;
 
    // Iterate over all the possible
    // intermediate values to reach N
    for (int i = 1; i <= N; i++) {
 
        dp[i] = 0;
 
        // Calculate the sum for
        // all 6 faces
        for (int j = 1; j <= 6; j++) {
 
            if (i - j >= 0) {
                dp[i] = dp[i] + dp[i - j];
            }
        }
    }
 
    // Print the total number of ways
    cout << dp[N];
}
 
// Driver Code
int main()
{
    // Given sum N
    int N = 4;
 
    // Function call
    findWays(N);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
  
class GFG{
  
// Function to calculate the total
// number of ways to have sum N
static void findWays(int N)
{
     
    // Initialize dp array
    int []dp = new int[N + 1];
  
    dp[0] = 1;
  
    // Iterate over all the possible
    // intermediate values to reach N
    for(int i = 1; i <= N; i++)
    {
        dp[i] = 0;
  
        // Calculate the sum for
        // all 6 faces
        for(int j = 1; j <= 6; j++)
        {
            if (i - j >= 0)
            {
                dp[i] = dp[i] + dp[i - j];
            }
        }
    }
  
    // Print the total number of ways
    System.out.print(dp[N]);
}
  
// Driver Code
public static void main(String[] args)
{
     
    // Given sum N
    int N = 4;
  
    // Function call
    findWays(N);
}
}
  
// This code is contributed by Amit Katiyar


Python3
# Python3 program for
# the above approach
 
# Function to calculate the total
# number of ways to have sum N
def findWays(N):
   
    # Initialize dp array
    dp = [0] * (N + 1);
    dp[0] = 1;
 
    # Iterate over all the
    # possible intermediate
    # values to reach N
    for i in range(1, N + 1):
        dp[i] = 0;
 
        # Calculate the sum for
        # all 6 faces
        for j in range(1, 7):
            if (i - j >= 0):
                dp[i] = dp[i] + dp[i - j];
 
    # Print total number of ways
    print(dp[N]);
 
# Driver Code
if __name__ == '__main__':
   
    # Given sum N
    N = 4;
 
    # Function call
    findWays(N);
 
# This code is contributed by 29AjayKumar


C#
// C# program for
// the above approach
using System;
class GFG{
  
// Function to calculate the total
// number of ways to have sum N
static void findWays(int N)
{
  // Initialize dp array
  int []dp = new int[N + 1];
 
  dp[0] = 1;
 
  // Iterate over all the possible
  // intermediate values to reach N
  for(int i = 1; i <= N; i++)
  {
    dp[i] = 0;
 
    // Calculate the sum for
    // all 6 faces
    for(int j = 1; j <= 6; j++)
    {
      if (i - j >= 0)
      {
        dp[i] = dp[i] + dp[i - j];
      }
    }
  }
 
  // Print the total number of ways
  Console.Write(dp[N]);
}
  
// Driver Code
public static void Main(String[] args)
{
  // Given sum N
  int N = 4;
 
  // Function call
  findWays(N);
}
}
 
// This code is contributed by 29AjayKumar


输出:
8









时间复杂度: O(6 N )
辅助空间: O(1)

动态编程方法:需要通过处理以下重叠的子问题来优化上述递归方法:

最佳子结构:对于每个状态,都会有6个状态重复发生,因此dp(N)的递归定义如下:

请按照以下步骤解决问题:

  • 使用初始值-1初始化大小为N + 1的辅助数组dp [] ,其中dp [i]存储具有和i的方式的数量。
  • 解决该问题的基本情况是,如果在任何状态下N等于0 ,则该状态的结果为1
  • 如果对于任何状态dp [i]不等于-1 ,则已经计算出此子结构的值。

自顶向下方法:以下是自顶向下方法的实现

C++

// C++ Program for the above approach
 
#include 
using namespace std;
 
// Function to calculate the total
// number of ways to have sum N
int findWays(int N, int dp[])
{
    // Base Case
    if (N == 0) {
        return 1;
    }
 
    // Return already stored result
    if (dp[N] != -1) {
 
        return dp[N];
    }
 
    int cnt = 0;
 
    // Recur for all 6 states
    for (int i = 1; i <= 6; i++) {
 
        if (N - i >= 0) {
            cnt = cnt
                  + findWays(N - i, dp);
        }
    }
 
    // Return the result
    return dp[N] = cnt;
}
 
// Driver Code
int main()
{
    // Given sum N
    int N = 4;
 
    // Initialize the dp array
    int dp[N + 1];
 
    memset(dp, -1, sizeof(dp));
 
    // Function Call
    cout << findWays(N, dp);
 
    return 0;
}

Java

// Java Program for
// the above approach
import java.util.*;
class GFG{
 
// Function to calculate the total
// number of ways to have sum N
static int findWays(int N, int dp[])
{
    // Base Case
    if (N == 0)
    {
        return 1;
    }
 
    // Return already
    // stored result
    if (dp[N] != -1)
    {
        return dp[N];
    }
 
    int cnt = 0;
 
    // Recur for all 6 states
    for (int i = 1; i <= 6; i++)
    {
        if (N - i >= 0)
        {
            cnt = cnt +
                  findWays(N - i, dp);
        }
    }
 
    // Return the result
    return dp[N] = cnt;
}
 
// Driver Code
public static void main(String[] args)
{
    // Given sum N
    int N = 4;
 
    // Initialize the dp array
    int []dp = new int[N + 1];
 
    for (int i = 0; i < dp.length; i++)
        dp[i] = -1;
 
    // Function Call
    System.out.print(findWays(N, dp));
}
}
 
// This code is contributed by 29AjayKumar

Python3

# Python3 Program for the
# above approach
 
# Function to calculate
# the total number of ways
# to have sum N
def findWays(N, dp):
 
    # Base Case
    if (N == 0):
        return 1
    
    # Return already
    # stored result
    if (dp[N] != -1):
        return dp[N]
 
    cnt = 0
 
    # Recur for all 6 states
    for i in range (1, 7):
        if (N - i >= 0):
            cnt = (cnt +
                   findWays(N - i, dp))
 
    # Return the result
    dp[N] = cnt
    return dp[N]
 
# Driver Code
if __name__ == "__main__":
 
    # Given sum N
    N = 4
 
    # Initialize the dp array
    dp = [-1] * (N + 1)
 
    # Function Call
    print(findWays(N, dp))
 
# This code is contributed by Chitranayal

C#

// C# Program for
// the above approach
using System;
class GFG{
 
// Function to calculate the total
// number of ways to have sum N
static int findWays(int N, int []dp)
{
  // Base Case
  if (N == 0)
  {
    return 1;
  }
 
  // Return already stored result
  if (dp[N] != -1)
  {
    return dp[N];
  }
 
  int cnt = 0;
 
  // Recur for all 6 states
  for (int i = 1; i <= 6; i++)
  {
    if (N - i >= 0)
    {
      cnt = cnt + findWays(N - i, dp);
    }
  }
 
  // Return the result
  return dp[N] = cnt;
}
 
// Driver Code
public static void Main(String[] args)
{
  // Given sum N
  int N = 4;
 
  // Initialize the dp array
  int []dp = new int[N + 1];
 
  for (int i = 0; i < dp.Length; i++)
    dp[i] = -1;
 
  // Function Call
  Console.Write(findWays(N, dp));
}
}
  
// This code is contributed by Rajput-Ji
输出:
8









时间复杂度: O(N)
辅助空间: O(N)

自底向上方法:下面是自底向上动态编程方法的实现:

C++

// C++ Program for the above approach
 
#include 
using namespace std;
 
// Function to calculate the total
// number of ways to have sum N
void findWays(int N)
{
    // Initialize dp array
    int dp[N + 1];
 
    dp[0] = 1;
 
    // Iterate over all the possible
    // intermediate values to reach N
    for (int i = 1; i <= N; i++) {
 
        dp[i] = 0;
 
        // Calculate the sum for
        // all 6 faces
        for (int j = 1; j <= 6; j++) {
 
            if (i - j >= 0) {
                dp[i] = dp[i] + dp[i - j];
            }
        }
    }
 
    // Print the total number of ways
    cout << dp[N];
}
 
// Driver Code
int main()
{
    // Given sum N
    int N = 4;
 
    // Function call
    findWays(N);
 
    return 0;
}

Java

// Java program for the above approach
import java.util.*;
  
class GFG{
  
// Function to calculate the total
// number of ways to have sum N
static void findWays(int N)
{
     
    // Initialize dp array
    int []dp = new int[N + 1];
  
    dp[0] = 1;
  
    // Iterate over all the possible
    // intermediate values to reach N
    for(int i = 1; i <= N; i++)
    {
        dp[i] = 0;
  
        // Calculate the sum for
        // all 6 faces
        for(int j = 1; j <= 6; j++)
        {
            if (i - j >= 0)
            {
                dp[i] = dp[i] + dp[i - j];
            }
        }
    }
  
    // Print the total number of ways
    System.out.print(dp[N]);
}
  
// Driver Code
public static void main(String[] args)
{
     
    // Given sum N
    int N = 4;
  
    // Function call
    findWays(N);
}
}
  
// This code is contributed by Amit Katiyar

Python3

# Python3 program for
# the above approach
 
# Function to calculate the total
# number of ways to have sum N
def findWays(N):
   
    # Initialize dp array
    dp = [0] * (N + 1);
    dp[0] = 1;
 
    # Iterate over all the
    # possible intermediate
    # values to reach N
    for i in range(1, N + 1):
        dp[i] = 0;
 
        # Calculate the sum for
        # all 6 faces
        for j in range(1, 7):
            if (i - j >= 0):
                dp[i] = dp[i] + dp[i - j];
 
    # Print total number of ways
    print(dp[N]);
 
# Driver Code
if __name__ == '__main__':
   
    # Given sum N
    N = 4;
 
    # Function call
    findWays(N);
 
# This code is contributed by 29AjayKumar

C#

// C# program for
// the above approach
using System;
class GFG{
  
// Function to calculate the total
// number of ways to have sum N
static void findWays(int N)
{
  // Initialize dp array
  int []dp = new int[N + 1];
 
  dp[0] = 1;
 
  // Iterate over all the possible
  // intermediate values to reach N
  for(int i = 1; i <= N; i++)
  {
    dp[i] = 0;
 
    // Calculate the sum for
    // all 6 faces
    for(int j = 1; j <= 6; j++)
    {
      if (i - j >= 0)
      {
        dp[i] = dp[i] + dp[i - j];
      }
    }
  }
 
  // Print the total number of ways
  Console.Write(dp[N]);
}
  
// Driver Code
public static void Main(String[] args)
{
  // Given sum N
  int N = 4;
 
  // Function call
  findWays(N);
}
}
 
// This code is contributed by 29AjayKumar
输出:
8









时间复杂度: O(N)
辅助空间: O(N)