给定两个整数N和K ,任务是计算所有数字的总和可被K整除的N个数字。
例子:
Input: N = 2, K = 7
Output: 12
Explanation: 2 digits numbers with sum divisible by 7 are: {16, 25, 34, 43, 52, 59, 61, 68, 70, 77, 86, 95}.
Therefore, the required output is 12.
Input: N = 1, K = 2
Output: 4
天真的方法:最简单的方法是遍历[10 (N – 1) ,10 N – 1]范围内的所有数字,并检查该范围内数字的所有数字的总和是否可被K整除?不是。对于发现条件为真的每个数字,增加count 。最后,打印计数。
时间复杂度: O(10 N – 10 N – 1-1)
辅助空间: O(1)
高效方法:想法是使用Digit DP技术来优化上述方法。以下是递归关系:
sum: represents sum of digits
st: check if a number contains any leading 0.
请按照以下步骤解决问题:
- 初始化3D数组dp [N] [K] [st],以计算和存储上述递归关系的所有子问题的值。
- 最后,返回dp [N] [sum%K] [st]的值。
C++
// C++ Program to implement
// the above approach
#include
using namespace std;
#define M 1000
// Function to count the N digit numbers
// whose sum is divisible by K
int countNum(int N, int sum, int K,
bool st, int dp[M][M][2])
{
// Base case
if (N == 0 and sum == 0) {
return 1;
}
if (N < 0) {
return 0;
}
// If already computed
// subproblem occurred
if (dp[N][sum][st] != -1) {
return dp[N][sum][st];
}
// Store the count of N digit numbers
// whoe sum is divisible by K
int res = 0;
// Check if the number does not contan
// any leading 0.
int start = st == 1 ? 0 : 1;
// Recurrence relation
for (int i = start; i <= 9; i++) {
res += countNum(N - 1, (sum + i) % K,
K, (st | i > 0), dp);
}
return dp[N][sum][st] = res;
}
// Driver Code
int main()
{
int N = 2, K = 7;
// Stores the values of
// overlapping subproblems
int dp[M][M][2];
memset(dp, -1, sizeof(dp));
cout << countNum(N, 0, K, 0, dp);
}
Java
// Java program to implement
// the above approach
import java.util.*;
import java.lang.*;
class GFG {
static final int M = 1000;
// Function to count the N digit numbers
// whose sum is divisible by K
static int countNum(int N, int sum, int K,
int st, int dp[][][])
{
// Base case
if (N == 0 && sum == 0) {
return 1;
}
if (N < 0) {
return 0;
}
// If already computed
// subproblem occurred
if (dp[N][sum][st] != -1) {
return dp[N][sum][st];
}
// Store the count of N digit numbers
// whoe sum is divisible by K
int res = 0;
// Check if the number does not contan
// any leading 0.
int start = st == 1 ? 0 : 1;
// Recurrence relation
for (int i = start; i <= 9; i++) {
res += countNum(N - 1, (sum + i) % K,
K, ((st | i) > 0) ? 1 : 0, dp);
}
return dp[N][sum][st] = res;
}
// Driver code
public static void main(String[] args)
{
int N = 2, K = 7;
// Stores the values of
// overlapping subproblems
int[][][] dp = new int[M][M][2];
for (int[][] i : dp)
for (int[] j : i)
Arrays.fill(j, -1);
System.out.print(countNum(N, 0, K, 0, dp));
}
}
// This code is contributed by offbeat
Python3
# Python3 program to implement
# the above approach
# Function to count the N digit
# numbers whose sum is divisible by K
def countNum(N, sum, K, st, dp):
# Base case
if (N == 0 and sum == 0):
return 1
if (N < 0):
return 0
# If already computed
# subproblem occurred
if (dp[N][sum][st] != -1):
return dp[N][sum][st]
# Store the count of N digit
# numbers whoe sum is divisible by K
res = 0
start = 1
# Check if the number does not contain
# any leading 0.
if (st == 1):
start = 0
else:
start = 1
# Recurrence relation
for i in range(start, 10):
min = 0
if ((st | i) > 0):
min = 1
else:
min = 0
res += countNum(N - 1, (sum + i) % K,
K, min, dp)
dp[N][sum][st] = res
return dp[N][sum][st]
# Driver code
if __name__ == '__main__':
N = 2
K = 7
M = 100
# Stores the values of
# overlapping subproblems
dp = [[[-1 for i in range(2)]
for j in range(M)]
for j in range(M)]
print(countNum(N, 0, K, 0, dp))
# This code is contributed by shikhasingrajput
C#
// C# program to implement
// the above approach
using System;
class GFG{
static int M = 1000;
// Function to count the N digit numbers
// whose sum is divisible by K
static int countNum(int N, int sum, int K,
int st, int[,, ] dp)
{
// Base case
if (N == 0 && sum == 0)
{
return 1;
}
if (N < 0)
{
return 0;
}
// If already computed
// subproblem occurred
if (dp[N, sum, st] != -1)
{
return dp[N, sum, st];
}
// Store the count of N digit numbers
// whoe sum is divisible by K
int res = 0;
// Check if the number does not contan
// any leading 0.
int start = (st == 1 ? 0 : 1);
// Recurrence relation
for(int i = start; i <= 9; i++)
{
res += countNum(N - 1, (sum + i) % K,
K, ((st | i) > 0) ? 1 : 0, dp);
}
return dp[N, sum, st] = res;
}
// Driver code
static public void Main()
{
int N = 2, K = 7;
// Stores the values of
// overlapping subproblems
int[,, ] dp = new int[M, M, 2];
for(int i = 0; i < M; i++)
for(int j = 0; j < M; j++)
for(int k = 0; k < 2; k++)
dp[i, j, k] = -1;
Console.WriteLine(countNum(N, 0, K, 0, dp));
}
}
// This code is contributed by offbeat
输出:
12
时间复杂度: O(10 * N * K)
辅助空间: O(N * K)