如果字符串仅由数字0到9组成,并且相邻元素不同,则称其为良。任务是找到所有长度为X并以给定数字Y结尾的可能字符串的数字总和。答案可能很大,因此请以10 9 + 7为模数打印答案。
例子:
Input: X = 2, Y = 2
Output: 61
All possible strings of length 2 that end with 2 are:
02, 12, 32, 42, 52, 62, 72, 82, 92.
Now, ((0 + 2) + (1 + 2) + (3 + 2) + (4 + 2) + (5 + 2)
+ (6 + 2) + (7 + 2) + (8 + 2) + (9 + 2)) = 61
Input: X = 6, Y = 4
Output: 1567751
方法:可以使用动态编程解决此问题。让我们定义以下状态:
- dp [i] [j]:所有可能的长度为i的良好字符串的数字总和,以j结尾。
- cnt [i] [j]:以j结尾的长度为i的良好字符串的计数。
由于必须比较相邻的数字是否相等,因此必须使用先前状态的值来计算当前状态的值。现在,递归关系将是:
dp[i][j] = dp[i][j] + dp[i – 1][k] + cnt[i – 1][k] * j
此处, dp [i – 1] [k]是长度为(i – 1)的好字符串的数字总和,以k和k!= j结尾。
cnt [i -1] [k]是长度为(i – 1)且以k和k!= j结尾的良好字符串的计数。
因此,对于位置i ,必须添加(cnt(i – 1)[k] * j) ,因为将j放在索引i上,并且长度为(i – 1)的可能字符串的计数为cnt [i – 1 ] [k] 。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
#define DIGITS 10
#define MAX 10000
#define MOD 1000000007
// To store the states of the dp
long dp[MAX][DIGITS], cnt[MAX][DIGITS];
// Function to fill the dp table
void precompute()
{
// dp[i][j] : Sum of the digits of all
// possible good strings of length
// i that end with j
// cnt[i][j] : Count of the good strings
// of length i that end with j
// Sum of digits of the string of length
// 1 is i as i is only number in that string
// and count of good strings of length 1
// that end with i is also 1
for (int i = 0; i < DIGITS; i++)
dp[1][i] = i, cnt[1][i] = 1;
for (int i = 2; i < MAX; i++) {
for (int j = 0; j < DIGITS; j++) {
for (int k = 0; k < DIGITS; k++) {
// Adjacent digits are different
if (j != k) {
dp[i][j] = dp[i][j]
+ (dp[i - 1][k] + (cnt[i - 1][k] * j) % MOD)
% MOD;
dp[i][j] %= MOD;
// Increment the count as digit at
// (i - 1)'th index is k and count
// of good strings is equal to this
// because at the end of the strings of
// length (i - 1) we are just
// putting digit j as the last digit
cnt[i][j] += cnt[i - 1][k];
cnt[i][j] %= MOD;
}
}
}
}
}
// Driver code
int main()
{
long long int x = 6, y = 4;
precompute();
cout << dp[x][y];
return 0;
}
Java
// Java implementation of the approach
class GFG
{
final static int DIGITS = 10;
final static int MAX = 10000;
final static int MOD = 1000000007;
// To store the states of the dp
static int dp[][] = new int[MAX][DIGITS];
static int cnt[][] = new int[MAX][DIGITS];
// Function to fill the dp table
static void precompute()
{
// dp[i][j] : Sum of the digits of all
// possible good strings of length
// i that end with j
// cnt[i][j] : Count of the good strings
// of length i that end with j
// Sum of digits of the string of length
// 1 is i as i is only number in that string
// and count of good strings of length 1
// that end with i is also 1
for (int i = 0; i < DIGITS; i++)
{
dp[1][i] = i;
cnt[1][i] = 1;
}
for (int i = 2; i < MAX; i++)
{
for (int j = 0; j < DIGITS; j++)
{
for (int k = 0; k < DIGITS; k++)
{
// Adjacent digits are different
if (j != k)
{
dp[i][j] = dp[i][j] + (dp[i - 1][k] +
(cnt[i - 1][k] * j) % MOD)
% MOD;
dp[i][j] %= MOD;
// Increment the count as digit at
// (i - 1)'th index is k and count
// of good strings is equal to this
// because at the end of the strings of
// length (i - 1) we are just
// putting digit j as the last digit
cnt[i][j] += cnt[i - 1][k];
cnt[i][j] %= MOD;
}
}
}
}
}
// Driver code
public static void main (String[] args)
{
int x = 6, y = 4;
precompute();
System.out.println(dp[x][y]);
}
}
// This code is contributed by AnkitRai01
Python3
# Python3 implementation of the approach
DIGITS = 10;
MAX = 10000;
MOD = 1000000007;
# To store the states of the dp
dp = [[0 for i in range(DIGITS)]
for i in range(MAX)];
cnt = [[0 for i in range(DIGITS)]
for i in range(MAX)];
# Function to fill the dp table
def precompute():
# dp[i][j] : Sum of the digits of all
# possible good strings of length
# i that end with j
# cnt[i][j] : Count of the good strings
# of length i that end with j
# Sum of digits of the string of length
# 1 is i as i is only number in that string
# and count of good strings of length 1
# that end with i is also 1
for i in range(DIGITS):
dp[1][i] = i;
cnt[1][i] = 1;
for i in range(2, MAX):
for j in range(DIGITS):
for k in range(DIGITS):
# Adjacent digits are different
if (j != k):
dp[i][j] = dp[i][j] + (dp[i - 1][k] +\
(cnt[i - 1][k] * j) % MOD) % MOD;
dp[i][j] %= MOD;
# Increment the count as digit at
# (i - 1)'th index is k and count
# of good strings is equal to this
# because at the end of the strings of
# length (i - 1) we are just
# putting digit j as the last digit
cnt[i][j] += cnt[i - 1][k];
cnt[i][j] %= MOD;
# Driver code
x = 6; y = 4;
precompute();
print(dp[x][y]);
# This code is contributed by 29AjayKumar
C#
// C# implementation of the approach
using System;
class GFG
{
readonly static int DIGITS = 10;
readonly static int MAX = 10000;
readonly static int MOD = 1000000007;
// To store the states of the dp
static int [,]dp = new int[MAX, DIGITS];
static int [,]cnt = new int[MAX, DIGITS];
// Function to fill the dp table
static void precompute()
{
// dp[i][j] : Sum of the digits of all
// possible good strings of length
// i that end with j
// cnt[i][j] : Count of the good strings
// of length i that end with j
// Sum of digits of the string of length
// 1 is i as i is only number in that string
// and count of good strings of length 1
// that end with i is also 1
for (int i = 0; i < DIGITS; i++)
{
dp[1, i] = i;
cnt[1, i] = 1;
}
for (int i = 2; i < MAX; i++)
{
for (int j = 0; j < DIGITS; j++)
{
for (int k = 0; k < DIGITS; k++)
{
// Adjacent digits are different
if (j != k)
{
dp[i, j] = dp[i, j] + (dp[i - 1, k] +
(cnt[i - 1, k] * j) % MOD)
% MOD;
dp[i, j] %= MOD;
// Increment the count as digit at
// (i - 1)'th index is k and count
// of good strings is equal to this
// because at the end of the strings of
// length (i - 1) we are just
// putting digit j as the last digit
cnt[i, j] += cnt[i - 1, k];
cnt[i, j] %= MOD;
}
}
}
}
}
// Driver code
public static void Main (String[] args)
{
int x = 6, y = 4;
precompute();
Console.WriteLine(dp[x,y]);
}
}
// This code is contributed by Rajput-Ji
1567751
时间复杂度: O(N)