📜  不包含重复元素的最大长度K的子序列数

📅  最后修改于: 2021-04-26 09:29:24             🧑  作者: Mango

给定一个由N个元素组成的数组arr []和一个正整数K ,使得K≤N 。任务是找到最大长度为K的子序列数,即具有所有不同元素的长度为0、1、2,…,K – 1,K的子序列。

例子:

方法:

  • 如果数组a []尚未排序,则对其进行排序,并在向量arr []中存储原始数组每个元素的频率。例如,如果a [] = { 2,2,3,3,5 },arr [] = {2,2,1},因为2出现两次,3出现两次,而5仅出现一次。
  • 假设m是向量arr []的长度。因此, m将是不同元素的数量。可能存在最大长度m的子序列,无需重复。如果m 则不存在长度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


输出:
18