给定一个包含N 个元素的数组arr[]和一个正整数K ,使得K ≤ N 。任务是找到最大长度为K的子序列的数量,即长度为 0, 1, 2, …, K – 1, K 的子序列的数量,这些子序列具有所有不同的元素。
例子:
Input: arr[] = {2, 2, 3, 3, 5}, K = 2
Output: 14
All the valid subsequences are {}, {2}, {2}, {3}, {3}, {5},
{2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 5}, {2, 5}, {3, 5} and {3, 5}.
Input: arr[] = {1, 2, 3, 4, 4}, K = 4
Output: 24
方法:
- 如果数组a[]尚未排序,则对其进行排序,并在向量arr[] 中存储原始数组的每个元素的频率。例如,如果a[] = {2, 2, 3, 3, 5}那么arr[] = {2, 2, 1}因为 2 出现了两次,3 出现了两次,而 5 只出现了一次。
- 假设m是向量arr[]的长度。所以m将是不同元素的数量。可以有不重复的最大长度 m 的子序列。如果m < k则没有长度为k 的子序列。因此,声明n = minimum(m, k) 。
- 现在应用动态规划。创建一个二维数组dp[n + 1][m + 1] ,这样dp[i][j]将存储长度为i的子序列的数量,这些子序列的第一个元素在arr[] 的第j个元素之后开始。例如, dp[1][1] = 3因为它表示数字
长度为 1 的子序列的第一个元素在arr[]的第一个元素之后开始,它们是 {3}, {3}, {5}。- 将dp[][] 的第一行初始化为1 。
- 在前一个循环内从上到下和从右到左运行两个循环。
- 如果j > m – i这意味着由于缺少元素,不可能有任何这样的序列。所以dp[i][j] = 0 。
- 否则, dp[i][j] = dp[i][j + 1] + arr[j] * dp[i – 1][j + 1]因为数字将是已经存在的长度为i 的子序列的数量加上由于重复,长度为i – 1的子序列的数量乘以arr[j] 。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Returns number of subsequences
// of maximum length k and
// contains no repeated element
int countSubSeq(int a[], int n, int k)
{
// Sort the array a[]
sort(a, a + n);
vector arr;
// Store the frequencies of all the
// distinct element in the vector arr
for (int i = 0; i < n;) {
int count = 1, x = a[i];
i++;
while (i < n && a[i] == x) {
count++;
i++;
}
arr.push_back(count);
}
int m = arr.size();
n = min(m, k);
// count is the the number
// of such subsequences
int count = 1;
// Create a 2-d array dp[n+1][m+1] to
// store the intermediate result
int dp[n + 1][m + 1];
// Initialize the first row to 1
for (int i = 0; i <= m; i++)
dp[0][i] = 1;
// Update the dp[][] array based
// on the recurrence relation
for (int i = 1; i <= n; i++) {
for (int j = m; j >= 0; j--) {
if (j > m - i)
dp[i][j] = 0;
else {
dp[i][j] = dp[i][j + 1]
+ arr[j] * dp[i - 1][j + 1];
}
}
count = count + dp[i][0];
}
// Return the number of subsequences
return count;
}
// Driver code
int main()
{
int a[] = { 2, 2, 3, 3, 5 };
int n = sizeof(a) / sizeof(int);
int k = 3;
cout << countSubSeq(a, n, k);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
// Returns number of subsequences
// of maximum length k and
// contains no repeated element
static int countSubSeq(int a[], int n, int k)
{
// Sort the array a[]
Arrays.sort(a);
List arr = new LinkedList<>();
// Store the frequencies of all the
// distinct element in the vector arr
for (int i = 0; i < n;)
{
int count = 1, x = a[i];
i++;
while (i < n && a[i] == x)
{
count++;
i++;
}
arr.add(count);
}
int m = arr.size();
n = Math.min(m, k);
// count is the the number
// of such subsequences
int count = 1;
// Create a 2-d array dp[n+1][m+1] to
// store the intermediate result
int [][]dp = new int[n + 1][m + 1];
// Initialize the first row to 1
for (int i = 0; i <= m; i++)
dp[0][i] = 1;
// Update the dp[][] array based
// on the recurrence relation
for (int i = 1; i <= n; i++)
{
for (int j = m; j >= 0; j--)
{
if (j > m - i)
dp[i][j] = 0;
else
{
dp[i][j] = dp[i][j + 1] +
arr.get(j) *
dp[i - 1][j + 1];
}
}
count = count + dp[i][0];
}
// Return the number of subsequences
return count;
}
// Driver code
public static void main(String[] args)
{
int a[] = { 2, 2, 3, 3, 5 };
int n = a.length;
int k = 3;
System.out.println(countSubSeq(a, n, k));
}
}
// This code is contributed by PrinciRaj1992
Python 3
# Python 3 implementation of the approach
# Returns number of subsequences
# of maximum length k and
# contains no repeated element
def countSubSeq(a, n, k):
# Sort the array a[]
a.sort(reverse = False)
arr = []
# Store the frequencies of all the
# distinct element in the vector arr
i = 0
while(i < n):
count = 1
x = a[i]
i += 1
while (i < n and a[i] == x):
count += 1
i += 1
arr.append(count)
m = len(arr)
n = min(m, k)
# count is the the number
# of such subsequences
count = 1
# Create a 2-d array dp[n+1][m+1] to
# store the intermediate result
dp = [[0 for i in range(m + 1)]
for j in range(n + 1)]
# Initialize the first row to 1
for i in range(m + 1):
dp[0][i] = 1
# Update the dp[][] array based
# on the recurrence relation
for i in range(1, n + 1, 1):
j = m
while(j >= 0):
if (j > m - i):
dp[i][j] = 0
else:
dp[i][j] = dp[i][j + 1] + \
arr[j] * dp[i - 1][j + 1]
j -= 1
count = count + dp[i][0]
# Return the number of subsequences
return count
# Driver code
if __name__ == '__main__':
a = [2, 2, 3, 3, 5]
n = len(a)
k = 3
print(countSubSeq(a, n, k))
# This code is contributed by Surendra_Gangwar
C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
class GFG
{
// Returns number of subsequences
// of maximum length k and
// contains no repeated element
static int countSubSeq(int []a, int n, int k)
{
// Sort the array a[]
Array.Sort(a);
List arr = new List();
int count, x;
// Store the frequencies of all the
// distinct element in the vector arr
for (int i = 0; i < n;)
{
count = 1;
x = a[i];
i++;
while (i < n && a[i] == x)
{
count++;
i++;
}
arr.Add(count);
}
int m = arr.Count;
n = Math.Min(m, k);
// count is the the number
// of such subsequences
count = 1;
// Create a 2-d array dp[n+1][m+1] to
// store the intermediate result
int [,]dp = new int[n + 1, m + 1];
// Initialize the first row to 1
for (int i = 0; i <= m; i++)
dp[0, i] = 1;
// Update the dp[][] array based
// on the recurrence relation
for (int i = 1; i <= n; i++)
{
for (int j = m; j >= 0; j--)
{
if (j > m - i)
dp[i, j] = 0;
else
{
dp[i, j] = dp[i, j + 1] +
arr[j] *
dp[i - 1, j + 1];
}
}
count = count + dp[i, 0];
}
// Return the number of subsequences
return count;
}
// Driver code
public static void Main(String[] args)
{
int []a = { 2, 2, 3, 3, 5 };
int n = a.Length;
int k = 3;
Console.WriteLine(countSubSeq(a, n, k));
}
}
// This code is contributed by 29AjayKumar
Javascript
输出:
18
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。