给定两个大小分别为N和M 的数组S[]和T[] 。任务是找到内容相同的S[] 的子序列和T[] 的子序列对。答案可能非常大。因此,打印答案模10 9 + 7 。
例子:
Input: S[] = {1, 1}, T[] = {1, 1}
Output: 6
Subsequences of S[] are {}, {1}, {1} and {1, 1}.
Subsequences of T[] are {}, {1}, {1} and {1, 1}.
All the valid pairs are ({}, {}), ({1}, {1}), ({1}, {1}),
({1}, {1}), ({1}, {1}) and ({1, 1}, {1, 1}).
Input: S[] = {1, 3}, T[] = {3, 1}
Output: 3
方法:让DP [i] [j]是方法来创建仅使用S [第i元素]和T []的第j个元素,使得所述子序列是相同的子序列的数量和第i个元件S[]和T[] 的第j个元素是子序列的一部分。
基本上,DP [i] [j]是答案的问题,如果仅S []和T的第j个元素的第一i个元素[]被考虑。如果S [I]!= T [j]的然后DP [i] [j] = 0,因为没有子序列将通过使用S的第i个元素[]和第j的T个元素结束[]。如果S[i] = T[j]那么dp[i][j] = ∑ k=1 i-1 ∑ l=1 j-1 dp[k][l] + 1因为S[]的前一个索引可以是任何索引≤ i并且T[]的前一个索引可以是任何索引≤ j 。
作为基本情况, dp[0][0] = 1 。这表示不采用任何元素的情况。它的运行时间是O(N 2 * M 2 )但我们可以通过预先计算总和来加快速度。
令sum[i][j] = ∑ k=1 i ∑ l=1 j dp[k][l]这是 dp 数组的二维前缀和。 sum[i][j] = sum[i – 1][j] + sum[i][j – 1] – sum[i – 1][j – 1] + dp[i][j] 。使用sum[i][j] ,现在可以在O(1) 中计算每个状态dp[i][j] 。
由于有N * M个状态,运行时间将为O(N * M) 。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
#define mod (int)(1e9 + 7)
// Function to return the pairs of subsequences
// from S[] and subsequences from T[] such
// that both have the same content
int subsequence(int S[], int T[], int n, int m)
{
// Create dp array
int dp[n + 1][m + 1];
// Base values
for (int i = 0; i <= n; i++)
dp[i][0] = 1;
// Base values
for (int j = 0; j <= m; j++)
dp[0][j] = 1;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
// Keep previous dp value
dp[i][j] = dp[i - 1][j]
+ dp[i][j - 1]
- dp[i - 1][j - 1];
// If both elements are same
if (S[i - 1] == T[j - 1])
dp[i][j] += dp[i - 1][j - 1];
dp[i][j] += mod;
dp[i][j] %= mod;
}
}
// Return the required answer
return dp[n][m];
}
// Driver code
int main()
{
int S[] = { 1, 1 };
int n = sizeof(S) / sizeof(S[0]);
int T[] = { 1, 1 };
int m = sizeof(T) / sizeof(T[0]);
cout << subsequence(S, T, n, m);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
// Function to return the pairs of subsequences
// from S[] and subsequences from T[] such
// that both have the same content
static int subsequence(int[] S, int[] T,
int n, int m)
{
// Create dp array
int [][] dp = new int[n + 1][m + 1];
int mod = 1000000007;
// Base values
for (int i = 0; i <= n; i++)
dp[i][0] = 1;
// Base values
for (int j = 0; j <= m; j++)
dp[0][j] = 1;
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
// Keep previous dp value
dp[i][j] = dp[i - 1][j] +
dp[i][j - 1] -
dp[i - 1][j - 1];
// If both elements are same
if (S[i - 1] == T[j - 1])
dp[i][j] += dp[i - 1][j - 1];
dp[i][j] += mod;
dp[i][j] %= mod;
}
}
// Return the required answer
return dp[n][m];
}
// Driver code
public static void main(String []args)
{
int S[] = { 1, 1 };
int n = S.length;
int T[] = { 1, 1 };
int m = T.length;
System.out.println(subsequence(S, T, n, m));
}
}
// This code is contributed by Sanjit Prasad
Python3
# Python3 implementation of the approach
import numpy as np
mod = int(1e9 + 7)
# Function to return the pairs of subsequences
# from S[] and subsequences from T[] such
# that both have the same content
def subsequence(S, T, n, m) :
# Create dp array
dp = np.zeros((n + 1, m + 1));
# Base values
for i in range(n + 1) :
dp[i][0] = 1;
# Base values
for j in range(m + 1) :
dp[0][j] = 1;
for i in range(1, n + 1) :
for j in range(1, m + 1) :
# Keep previous dp value
dp[i][j] = dp[i - 1][j] + dp[i][j - 1] - \
dp[i - 1][j - 1];
# If both elements are same
if (S[i - 1] == T[j - 1]) :
dp[i][j] += dp[i - 1][j - 1];
dp[i][j] += mod;
dp[i][j] %= mod;
# Return the required answer
return dp[n][m];
# Driver code
if __name__ == "__main__" :
S = [ 1, 1 ];
n = len(S);
T = [ 1, 1 ];
m = len(T);
print(subsequence(S, T, n, m));
# This code is contributed by kanugargng
C#
// C# implementation of the approach
using System;
class GFG
{
// Function to return the pairs of subsequences
// from S[] and subsequences from T[] such
// that both have the same content
static int subsequence(int[] S, int[] T,
int n, int m)
{
// Create dp array
int [,] dp = new int[n + 1, m + 1];
int mod = 1000000007;
// Base values
for (int i = 0; i <= n; i++)
dp[i, 0] = 1;
// Base values
for (int j = 0; j <= m; j++)
dp[0, j] = 1;
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
// Keep previous dp value
dp[i, j] = dp[i - 1, j] +
dp[i, j - 1] -
dp[i - 1, j - 1];
// If both elements are same
if (S[i - 1] == T[j - 1])
dp[i, j] += dp[i - 1, j - 1];
dp[i, j] += mod;
dp[i, j] %= mod;
}
}
// Return the required answer
return dp[n, m];
}
// Driver code
public static void Main()
{
int []S = { 1, 1 };
int n = S.Length;
int []T = { 1, 1 };
int m = T.Length;
Console.WriteLine(subsequence(S, T, n, m));
}
}
// This code is contributed by AnkitRai01
Javascript
6
时间复杂度:O(N*M)
辅助空间:O(N*M)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。