📜  在子字符串中划分字符串的方法数,使它们按字典序递增

📅  最后修改于: 2021-09-22 10:20:30             🧑  作者: Mango

给定一个字符串S ,任务是找到在子字符串S1, S2, S3, …, Sk 中划分/划分给定字符串的方法数量,使得S1 < S2 < S3 < … < Sk (按字典顺序)。
例子:

方法:这个问题可以用动态规划解决。

  • DP[i][j]定义为划分子串S[0…j] 的方法数,使得S[i, j]是最后一个分区。
  • 现在,递归关系将是DP[i][j] = (DP[k][i – 1])对于所有k ≥ 0i ≤ N – 1 的总和,其中N是字符串的长度。
  • 最终答案将是(DP[i][N – 1])对于0N – 1之间的所有i的总和,因为这些子字符串将成为某些可能的分区方式中的最后一个分区。
  • 所以,这里对于所有子串S[i][j] ,找到子串S[k][i – 1]使得S[k][i – 1]在字典上小于S[i] [j]并将DP[k][i – 1] 添加DP[i][j]

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Function to return the number of
// ways of partioning
int ways(string s, int n)
{
 
    int dp[n][n];
 
    // Initialize DP table
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++) {
            dp[i][j] = 0;
        }
 
    // Base Case
    for (int i = 0; i < n; i++)
        dp[0][i] = 1;
 
    for (int i = 1; i < n; i++) {
 
        // To store sub-string S[i][j]
        string temp;
        for (int j = i; j < n; j++) {
            temp += s[j];
 
            // To store sub-string S[k][i-1]
            string test;
            for (int k = i - 1; k >= 0; k--) {
                test += s[k];
                if (test < temp) {
                    dp[i][j] += dp[k][i - 1];
                }
            }
        }
    }
 
    int ans = 0;
    for (int i = 0; i < n; i++) {
        // Add all the ways where S[i][n-1]
        // will be the last partition
        ans += dp[i][n - 1];
    }
 
    return ans;
}
 
// Driver code
int main()
{
    string s = "aabc";
    int n = s.length();
 
    cout << ways(s, n);
 
    return 0;
}


Java
// Java implementation of the above approach
class GFG
{
    // Function to return the number of
    // ways of partioning
    static int ways(String s, int n)
    {
        int dp[][] = new int[n][n];
     
        // Initialize DP table
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
            {
                dp[i][j] = 0;
            }
     
        // Base Case
        for (int i = 0; i < n; i++)
            dp[0][i] = 1;
     
        for (int i = 1; i < n; i++)
        {
     
            // To store sub-string S[i][j]
            String temp = "";
            for (int j = i; j < n; j++)
            {
                temp += s.charAt(j);
     
                // To store sub-string S[k][i-1]
                String test = "";
                for (int k = i - 1; k >= 0; k--)
                {
                    test += s.charAt(k);
                    if (test.compareTo(temp) < 0)
                    {
                        dp[i][j] += dp[k][i - 1];
                    }
                }
            }
        }
     
        int ans = 0;
        for (int i = 0; i < n; i++)
        {
            // Add all the ways where S[i][n-1]
            // will be the last partition
            ans += dp[i][n - 1];
        }
        return ans;
    }
     
    // Driver code
    public static void main (String[] args)
    {
        String s = "aabc";
        int n = s.length();
     
        System.out.println(ways(s, n));
    }
}
 
// This code is contributed by AnkitRai01


Python3
# Python3 implementation of the approach
 
# Function to return the number of
# ways of partioning
def ways(s, n):
 
    dp = [[0 for i in range(n)]
             for i in range(n)]
 
    # Base Case
    for i in range(n):
        dp[0][i] = 1
 
    for i in range(1, n):
 
        # To store sub-S[i][j]
        temp = ""
        for j in range(i, n):
            temp += s[j]
 
            # To store sub-S[k][i-1]
            test = ""
            for k in range(i - 1, -1, -1):
                test += s[k]
                if (test < temp):
                    dp[i][j] += dp[k][i - 1]
 
    ans = 0
    for i in range(n):
         
        # Add all the ways where S[i][n-1]
        # will be the last partition
        ans += dp[i][n - 1]
 
    return ans
 
# Driver code
s = "aabc"
n = len(s)
 
print(ways(s, n))
 
# This code is contributed by Mohit Kumarv


C#
// C# implementation of the above approach
using System;
 
class GFG
{
    // Function to return the number of
    // ways of partioning
    static int ways(String s, int n)
    {
        int [,]dp = new int[n, n];
     
        // Initialize DP table
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
            {
                dp[i, j] = 0;
            }
     
        // Base Case
        for (int i = 0; i < n; i++)
            dp[0, i] = 1;
     
        for (int i = 1; i < n; i++)
        {
     
            // To store sub-string S[i,j]
            String temp = "";
            for (int j = i; j < n; j++)
            {
                temp += s[j];
     
                // To store sub-string S[k,i-1]
                String test = "";
                for (int k = i - 1; k >= 0; k--)
                {
                    test += s[k];
                    if (test.CompareTo(temp) < 0)
                    {
                        dp[i, j] += dp[k, i - 1];
                    }
                }
            }
        }
     
        int ans = 0;
        for (int i = 0; i < n; i++)
        {
            // Add all the ways where S[i,n-1]
            // will be the last partition
            ans += dp[i, n - 1];
        }
        return ans;
    }
     
    // Driver code
    public static void Main (String[] args)
    {
        String s = "aabc";
        int n = s.Length;
     
        Console.WriteLine(ways(s, n));
    }
}
 
// This code is contributed by PrinciRaj1992


Javascript


输出:
6

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程