给定N个元素的数组arr [] 。任务是找到具有至少两个连续元素的子序列的数量,以使它们之间的绝对差≤1 。
例子:
Input: arr[] = {1, 6, 2, 1}
Output: 6
{1, 2}, {1, 2, 1}, {2, 1}, {6, 2, 1}, {1, 1} and {1, 6, 2, 1}
are the sub-sequences that have at least one consecutive pair
with difference less than or equal to 1.
Input: arr[] = {1, 6, 2, 1, 9}
Output: 12
幼稚的方法:想法是找到所有可能的子序列,并检查是否存在相差≤1的任何连续对的子序列,并增加计数。
高效的方法:想法是遍历给定的数组,对于每个ith元素,尝试找到所需的以ith元素作为最后一个元素结尾的子序列。
对于每个i,我们要使用arr [i],arr [i] -1,arr [i] + 1,因此我们将定义2D数组dp [] [] ,其中dp [i] [0]将包含不具有相差小于1的任何连续对的子序列数和dp [i] [1]包含具有相差≤1的任何连续对的子序列数。
另外,我们将维护两个变量required_subsequence和not_required_subsdequence,以维护具有至少一个连续元素差≤1的子序列的计数和不包含任何具有差值≤1的连续元素对的子序列的计数。
现在,考虑子数组arr [1]…。 arr [i],我们将执行以下步骤:
- 通过在子序列中添加第ith个元素,可以计算出不具有相差小于1的连续对的子序列的数目。这些基本上是dp [arr [i] + 1] [0],dp [arr [i] – 1] [0]和dp [arr [i]] [0]的总和。
- 子序列的总数具有至少一个连续的对,其差值至少为1,并且在i处终止,直到找到i为止的总子序列(仅在最后追加arr [i])+变成子序列的子序列具有加arr [i]时,至少有一对小于1的连续对。
- 在i + 1之前不具有相差小于1且不小于1的连续对的总子序列=在i + 1之前不具有相差小于1的任何连续对的总子序列(仅将当前元素作为子序列) 。
- 更新required_sub-sequence,not_required_subsequence和dp [arr [i] [0]],最终答案将为required_subsequence。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
const int N = 10000;
// Function to return the number of subsequences
// which have at least one consecutive pair
// with difference less than or equal to 1
int count_required_sequence(int n, int arr[])
{
int total_required_subsequence = 0;
int total_n_required_subsequence = 0;
int dp[N][2];
for (int i = 0; i < n; i++) {
// Not required sub-sequences which
// turn required on adding i
int turn_required = 0;
for (int j = -1; j <= 1; j++)
turn_required += dp[arr[i] + j][0];
// Required sub-sequence till now will be
// required sequence plus sub-sequence
// which turns required
int required_end_i = (total_required_subsequence
+ turn_required);
// Similarly for not required
int n_required_end_i = (1 + total_n_required_subsequence
- turn_required);
// Also updating total required and
// not required sub-sequences
total_required_subsequence += required_end_i;
total_n_required_subsequence += n_required_end_i;
// Also, storing values in dp
dp[arr[i]][1] += required_end_i;
dp[arr[i]][0] += n_required_end_i;
}
return total_required_subsequence;
}
// Driver code
int main()
{
int arr[] = { 1, 6, 2, 1, 9 };
int n = sizeof(arr) / sizeof(int);
cout << count_required_sequence(n, arr) << "\n";
return 0;
}
Java
// Java implemenation of above approach
public class GFG
{
static int N = 10000;
// Function to return the number of subsequences
// which have at least one consecutive pair
// with difference less than or equal to 1
static int count_required_sequence(int n, int arr[])
{
int total_required_subsequence = 0;
int total_n_required_subsequence = 0;
int [][]dp = new int[N][2];
for (int i = 0; i < n; i++)
{
// Not required sub-sequences which
// turn required on adding i
int turn_required = 0;
for (int j = -1; j <= 1; j++)
turn_required += dp[arr[i] + j][0];
// Required sub-sequence till now will be
// required sequence plus sub-sequence
// which turns required
int required_end_i = (total_required_subsequence
+ turn_required);
// Similarly for not required
int n_required_end_i = (1 + total_n_required_subsequence
- turn_required);
// Also updating total required and
// not required sub-sequences
total_required_subsequence += required_end_i;
total_n_required_subsequence += n_required_end_i;
// Also, storing values in dp
dp[arr[i]][1] += required_end_i;
dp[arr[i]][0] += n_required_end_i;
}
return total_required_subsequence;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 1, 6, 2, 1, 9 };
int n = arr.length;
System.out.println(count_required_sequence(n, arr));
}
}
// This code has been contributed by 29AjayKumar
Python3
# Python3 implementation of the approach
import numpy as np;
N = 10000;
# Function to return the number of subsequences
# which have at least one consecutive pair
# with difference less than or equal to 1
def count_required_sequence(n, arr) :
total_required_subsequence = 0;
total_n_required_subsequence = 0;
dp = np.zeros((N,2));
for i in range(n) :
# Not required sub-sequences which
# turn required on adding i
turn_required = 0;
for j in range(-1, 2,1) :
turn_required += dp[arr[i] + j][0];
# Required sub-sequence till now will be
# required sequence plus sub-sequence
# which turns required
required_end_i = (total_required_subsequence
+ turn_required);
# Similarly for not required
n_required_end_i = (1 + total_n_required_subsequence
- turn_required);
# Also updating total required and
# not required sub-sequences
total_required_subsequence += required_end_i;
total_n_required_subsequence += n_required_end_i;
# Also, storing values in dp
dp[arr[i]][1] += required_end_i;
dp[arr[i]][0] += n_required_end_i;
return total_required_subsequence;
# Driver code
if __name__ == "__main__" :
arr = [ 1, 6, 2, 1, 9 ];
n = len(arr);
print(count_required_sequence(n, arr)) ;
# This code is contributed by AnkitRai01
C#
// C# implementation of the above approach
using System;
class GFG
{
static int N = 10000;
// Function to return the number of subsequences
// which have at least one consecutive pair
// with difference less than or equal to 1
static int count_required_sequence(int n, int []arr)
{
int total_required_subsequence = 0;
int total_n_required_subsequence = 0;
int [, ]dp = new int[N, 2];
for (int i = 0; i < n; i++)
{
// Not required sub-sequences which
// turn required on adding i
int turn_required = 0;
for (int j = -1; j <= 1; j++)
turn_required += dp[arr[i] + j, 0];
// Required sub-sequence till now will be
// required sequence plus sub-sequence
// which turns required
int required_end_i = (total_required_subsequence
+ turn_required);
// Similarly for not required
int n_required_end_i = (1 + total_n_required_subsequence
- turn_required);
// Also updating total required and
// not required sub-sequences
total_required_subsequence += required_end_i;
total_n_required_subsequence += n_required_end_i;
// Also, storing values in dp
dp[arr[i], 1] += required_end_i;
dp[arr[i], 0] += n_required_end_i;
}
return total_required_subsequence;
}
// Driver code
public static void Main()
{
int [] arr = new int [] { 1, 6, 2, 1, 9 };
int n = arr.Length;
Console.WriteLine(count_required_sequence(n, arr));
}
}
// This code has been contributed by ihritik
12