[Dynamic Programming Question 18] (hard) palindrome substring && (hard) longest palindrome substring

1745. Split palindrome string IV

Link: 1745. Split palindrome string IV

Given a string s, if it can be split into three non-empty palindrome substrings, then return true, otherwise return false.
When a string is read exactly the same upright and backwards, it is called a palindrome string.

Example 1:

Input: s = "abcbdd"
Output: true
Explanation: "abcbdd" = "a" + "bcb" + "dd", the three substrings are palindromes.
Example 2:

Input: s = "bcbddxy"
Output: false
Explanation: s cannot be split into 3 palindrome substrings.

Solution:
Algorithm idea:
The question requires a string to be divided into "three non-empty reply text substrings". At first glance, there are many states to be expressed, and some are difficult to start with.

In fact, we can split it into "two small problems":
i. Dynamic programming to solve whether a non-empty substring in the string is a palindrome string;
ii. Enumerate three substrings except the string endpoints The starting point is to query whether these three non-empty substrings are back-text strings.
Then this difficult question will be turned into a simple question in no time, and it will become an enumeration question.

Code:

  bool checkPartitioning(string s) {
    
    
           int n=s.size();
        vector<vector<bool>> dp(n,vector<bool>(n));
        dp[0][0]=1;

        for(int j=1;j<n;j++)
        {
    
    
            dp[j][j]=1;
            for(int i=0;i<=j;i++)
            {
    
    
                if(s[i]==s[j])
                {
    
    
                    if(j==i+1) dp[i][j]=1;
                    if(j>i+1)  dp[i][j]=dp[i+1][j-1];
                }
            }
        }
       
        for(int i=1;i<n-1;i++)
        {
    
    
            for(int j=0;j<i;j++)
            {
    
    
                if(dp[0][j]&&dp[j+1][i]&&dp[i+1][n-1])
                return true;
            }
        }
        return false;

    }

Insert image description here

132. Split palindrome string II

Link: 132. Split Palindrome String II
gives you a string s. Please split s into some substrings so that each substring is a palindrome.

Returns the minimum number of divisions that meet the requirements.

Example 1:

Input: s = "aab"
Output: 1
Explanation: It only takes one split to split s into two palindrome substrings ["aa", "b"].
Example 2:

Input: s = "a"
Output: 0
Example 3:

Input: s = "ab"
Output: 1

Algorithm idea:

  1. State representation:
    Based on "experience", continue to try to use the i position as the end, define the state representation, and see if it can solve the problem:
    dp[i] represents: the string in the [0, i] interval in s, at least number of divisions

1. State representation *
Based on "experience", continue to try to use the i position as the end, define the state representation, and see if it can solve the problem:
dp[i] represents: the string in the [0, i] interval in s, Minimum number of times to split the string.

2. State transition equation.
State transition equations are generally analyzed based on the information of the "last position": assuming 0 <= j <= i, then we can determine whether the substring at the j ~ i position is a palindrome. Strings are divided into the following two categories:

  • i. When the substring at position [j,i] can form a palindrome, then dp[i] is equal to the minimum number of palindrome strings in the interval [0, j - 1] + 1, that isdp[i] = dp[j - 1] + 1 ;
  • ii. When the substring at the [j,i] position cannot form a palindrome string, the j position does not need to be considered.

3. Initialization
Observing the "state transition equation", we will use the value of the j-1 position. We can think about it. When j == 0, the represented interval is [0, i]. If the string in the interval [0, i] is already a polyphasis string, the smallest polyphasis string is the one, and the subsequent values ​​of j do not need to be traversed.
Therefore, we can handle the case where j == 0 before looping over the values ​​of j, and then starting the loop from 1.
However, to prevent min operations, 0 interferes with the results. Let’s first initialize the value on the table to “infinity”

4. The order of filling in the form
is from left to right

5. Return value
According to the "status indication", dp[n - 1] should be returned

Code:

 int minCut(string s) {
    
    

  int n=s.size();
        vector<vector<bool>> dp(n,vector<bool>(n));

        dp[0][0]=1;
        for(int j=1;j<n;j++)
        {
    
    
            dp[j][j]=1;
            for(int i=0;i<=j;i++)
            {
    
    
                if(s[i]==s[j])
                {
    
    
                    if(j==i+1)  dp[i][j]=1;
                    if(j>i+1)   dp[i][j]=dp[i+1][j-1];
                }
            }
        }

        vector<int> dp1(n,INT_MAX-500);
        dp1[0]=0;
        
        for(int i=1;i<n;i++)
        {
    
    
            if(dp[0][i]) dp1[i]=0;
            else
            {
    
    
                for(int j=1;j<=i;j++)
                {
    
    
                    if(dp[j][i])
                        dp1[i]=min(dp1[i],dp1[j-1]+1);
                }
            }
        }
        return dp1[n-1];
    }

Insert image description here

Guess you like

Origin blog.csdn.net/m0_64579278/article/details/133221087