大小为 N 的数组的计数,相邻元素之间的绝对差最多为 1
给定一个正整数M和一个大小为N的数组arr[]并且在表示为-1的数组中缺少一些整数,任务是在将所有-1替换为范围[ 1, M]使得任何一对相邻元素之间的绝对差最多为1 。
例子:
Input: arr[] = {2, -1, 2}, M = 5
Output: 3
Explanation:
The arrays that follow the given conditions are {2, 1, 2}, {2, 2, 2} and {2, 3, 2}.
Input: arr[] = {4, -1, 2, 1, -1, -1}, M = 10
Output: 5
方法:给定的问题可以使用基于以下观察的动态规划来解决:
- 考虑一个二维数组,例如dp[][]其中dp[i][j]表示长度为i+1且最后一个元素为j的有效数组的计数。
- 由于任何相邻元素之间的绝对差最多只能为1 ,因此对于任何整数j ,有效的相邻整数可以是j-1 、 j和j+1 。因此,可以使用以下关系计算任何状态dp[i][j] :
dp[ i ][ j ] = dp[ i-1 ][ j ] + dp[ i-1 ][ j-1 ] + dp[ i-1 ][ j+1 ]
- 在arr[i] = -1的情况下,计算dp[i][j] = (dp[i-1][j] + dp[i-1][j-1] + dp[i-1][ j+1])用于[1, M]范围内的所有j值。
- 在arr[i] != -1的情况下,计算dp[i][j] = (dp[i-1][j] + dp[i-1][j-1] + dp[i-1] [j+1])对于j = arr[i] 。
- 请注意,在arr[0] = -1的情况下,范围[1, M]中的所有值都可以作为第一个数组元素访问,因此为范围[1 ] 中的所有j初始化dp[0][j] = 1 , M]否则初始化dp[0][arr[0]] = 1 。
- 所需答案将是[1, M]范围内所有j的所有dp[N – 1][j]值的总和。
下面是上述方法的实现:
C++
// C++ program of the above approach
#include
using namespace std;
// Function to find the count of possible
// arrays such that the absolute difference
// between any adjacent elements is atmost 1
int countArray(int arr[], int N, int M)
{
// Stores the dp states where dp[i][j]
// represents count of arrays of length
// i+1 having their last element as j
int dp[N][M + 2];
memset(dp, 0, sizeof dp);
// Case where 1st array element is missing
if (arr[0] == -1) {
// All integers in range [1, M]
// are reachable
for (int j = 1; j <= M; j++) {
dp[0][j] = 1;
}
}
else {
// Only reachable integer is arr[0]
dp[0][arr[0]] = 1;
}
// Iterate through all values of i
for (int i = 1; i < N; i++) {
// If arr[i] is not missing
if (arr[i] != -1) {
// Only valid value of j is arr[i]
int j = arr[i];
dp[i][j] += dp[i - 1][j - 1] + dp[i - 1][j]
+ dp[i - 1][j + 1];
}
// If arr[i] is missing
if (arr[i] == -1) {
// Iterate through all possible
// values of j in range [1, M]
for (int j = 1; j <= M; j++) {
dp[i][j] += dp[i - 1][j - 1] + dp[i - 1][j]
+ dp[i - 1][j + 1];
}
}
}
// Stores the count of valid arrays
int arrCount = 0;
// Calculate the total count of
// valid arrays
for (int j = 1; j <= M; j++) {
arrCount += dp[N - 1][j];
}
// Return answer
return arrCount;
}
// Driver Code
int main()
{
int arr[] = { 4, -1, 2, 1, -1, -1 };
int N = sizeof(arr) / sizeof(arr[0]);
int M = 10;
// Function Call
cout << countArray(arr, N, M);
return 0;
}
Java
// Java program of the above approach
class GFG
{
// Function to find the count of possible
// arrays such that the absolute difference
// between any adjacent elements is atmost 1
public static int countArray(int arr[], int N, int M)
{
// Stores the dp states where dp[i][j]
// represents count of arrays of length
// i+1 having their last element as j
int[][] dp = new int[N][M + 2];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M + 2; j++) {
dp[i][j] = 0;
}
}
// Case where 1st array element is missing
if (arr[0] == -1)
{
// All integers in range [1, M]
// are reachable
for (int j = 1; j <= M; j++) {
dp[0][j] = 1;
}
} else {
// Only reachable integer is arr[0]
dp[0][arr[0]] = 1;
}
// Iterate through all values of i
for (int i = 1; i < N; i++) {
// If arr[i] is not missing
if (arr[i] != -1) {
// Only valid value of j is arr[i]
int j = arr[i];
dp[i][j] += dp[i - 1][j - 1] + dp[i - 1][j] + dp[i - 1][j + 1];
}
// If arr[i] is missing
if (arr[i] == -1) {
// Iterate through all possible
// values of j in range [1, M]
for (int j = 1; j <= M; j++) {
dp[i][j] += dp[i - 1][j - 1] + dp[i - 1][j] + dp[i - 1][j + 1];
}
}
}
// Stores the count of valid arrays
int arrCount = 0;
// Calculate the total count of
// valid arrays
for (int j = 1; j <= M; j++) {
arrCount += dp[N - 1][j];
}
// Return answer
return arrCount;
}
// Driver Code
public static void main(String args[]) {
int arr[] = { 4, -1, 2, 1, -1, -1 };
int N = arr.length;
int M = 10;
// Function Call
System.out.println(countArray(arr, N, M));
}
}
// This code is contributed by _saurabh_jaiswal.
Python3
# Python 3 program of the above approach
# Function to find the count of possible
# arrays such that the absolute difference
# between any adjacent elements is atmost 1
def countArray(arr, N, M):
# Stores the dp states where dp[i][j]
# represents count of arrays of length
# i+1 having their last element as j
dp = [[0 for i in range(M+2)] for j in range(N)]
# Case where 1st array element is missing
if (arr[0] == -1):
# All integers in range [1, M]
# are reachable
for j in range(1,M+1,1):
dp[0][j] = 1
else:
# Only reachable integer is arr[0]
dp[0][arr[0]] = 1
# Iterate through all values of i
for i in range(1, N, 1):
# If arr[i] is not missing
if(arr[i] != -1):
# Only valid value of j is arr[i]
j = arr[i]
dp[i][j] += dp[i - 1][j - 1] + dp[i - 1][j] + dp[i - 1][j + 1]
# If arr[i] is missing
if (arr[i] == -1):
# Iterate through all possible
# values of j in range [1, M]
for j in range(1,M+1,1):
dp[i][j] += dp[i - 1][j - 1] + dp[i - 1][j] + dp[i - 1][j + 1]
# Stores the count of valid arrays
arrCount = 0
# Calculate the total count of
# valid arrays
for j in range(1,M+1,1):
arrCount += dp[N - 1][j]
# Return answer
return arrCount
# Driver Code
if __name__ == '__main__':
arr = [4, -1, 2, 1, -1, -1]
N = len(arr)
M = 10
# Function Call
print(countArray(arr, N, M))
# This code is contributed by SURENDRA_GANGWAR.
C#
// C# program of the above approach
using System;
public class GFG
{
// Function to find the count of possible
// arrays such that the absolute difference
// between any adjacent elements is atmost 1
public static int countArray(int []arr, int N, int M)
{
// Stores the dp states where dp[i][j]
// represents count of arrays of length
// i+1 having their last element as j
int[,] dp = new int[N, M + 2];
for (int i = 0; i < N; i++) {
for (int j = 0; j < M + 2; j++) {
dp[i, j] = 0;
}
}
// Case where 1st array element is missing
if (arr[0] == -1)
{
// All integers in range [1, M]
// are reachable
for (int j = 1; j <= M; j++) {
dp[0, j] = 1;
}
} else {
// Only reachable integer is arr[0]
dp[0, arr[0]] = 1;
}
// Iterate through all values of i
for (int i = 1; i < N; i++) {
// If arr[i] is not missing
if (arr[i] != -1) {
// Only valid value of j is arr[i]
int j = arr[i];
dp[i, j] += dp[i - 1, j - 1] + dp[i - 1, j] + dp[i - 1, j + 1];
}
// If arr[i] is missing
if (arr[i] == -1) {
// Iterate through all possible
// values of j in range [1, M]
for (int j = 1; j <= M; j++) {
dp[i, j] += dp[i - 1, j - 1] + dp[i - 1, j] + dp[i - 1, j + 1];
}
}
}
// Stores the count of valid arrays
int arrCount = 0;
// Calculate the total count of
// valid arrays
for (int j = 1; j <= M; j++) {
arrCount += dp[N - 1, j];
}
// Return answer
return arrCount;
}
// Driver Code
public static void Main(String[] args) {
int []arr = { 4, -1, 2, 1, -1, -1 };
int N = arr.Length;
int M = 10;
// Function Call
Console.WriteLine(countArray(arr, N, M));
}
}
// This code is contributed by AnkThon.
Javascript
输出:
5
时间复杂度: O(N*M)
辅助空间: O(N*M)