• Leetcode_1278. Palindrome Partitioning III_[DP]


    题目链接

    You are given a string s containing lowercase letters and an integer k. You need to :

    • First, change some characters of s to other lowercase English letters.
    • Then divide s into k non-empty disjoint substrings such that each substring is palindrome.

    Return the minimal number of characters that you need to change to divide the string.

    Example 1:

    Input: s = "abc", k = 2
    Output: 1
    Explanation: You can split the string into "ab" and "c", and change 1 character in "ab" to make it palindrome.
    

    Example 2:

    Input: s = "aabbc", k = 3
    Output: 0
    Explanation: You can split the string into "aa", "bb" and "c", all of them are palindrome.

    Example 3:

    Input: s = "leetcode", k = 8
    Output: 0
    

    Constraints:

    • 1 <= k <= s.length <= 100.
    • s only contains lowercase English letters.

    解法:

    Leetcode_132. Palindrome Partitioning II解法,这道题可以有一个比较清晰的思路。

    动态规划:dp[idx][k]表示将s[idx : s.size())这个子串划分为k个非空回文子串最少需要改变的字符数。

    递归关系:dp[0][k] = min( f(0,idx-1) + dp[idx][k-1]), for idx in [0, s.size()-1],

    其中 f(0,idx-1) == 0 if(s[0,idx-1] is palendrome),else f(0,idx-1) == number of chars that have to change.

    需要注意,对于dp[idx][k],如果s.size()-idx < k,那么无论如何也不能将s[idx, s.size()-1]划分为k个回文子串。

    class Solution {
    public:
        vector<vector<bool>> is_palindrome;
        vector<vector<int>> dp;
        int palindromePartition(string s, int k) {
            int len = s.size();
            is_palindrome = std::move(vector<vector<bool>>(len, vector<bool>(len, false)));
            dp = std::move(vector<vector<int>>(len, vector<int>(k+1, INT_MAX)));
            for(int l=1; l<=len; l++)
                for(int head=0; head+l-1<len; head++){
                    int tail = head+l-1;
                    if(l == 1)
                        is_palindrome[head][head] = true;
                    else if(l == 2)
                        is_palindrome[head][tail] = s[head]==s[tail];
                    else
                        is_palindrome[head][tail] = (s[head]==s[tail] && is_palindrome[head+1][tail-1]);
                }
    
            dfs(s, 0, k);
            return dp[0][k];
        }
    
        int dfs(string &s, int idx, int k){
            if(idx == s.size())
                return k==0 ? 0 : s.size();
            if(dp[idx][k]<INT_MAX)
                return dp[idx][k];
            int ret = s.size()+1;
            for(int l=1; idx+l-1+k-1<s.size(); l++){
                int behind = dfs(s, idx+l, k-1), use = 0;
                if(!is_palindrome[idx][idx+l-1]){
                    for(int head=idx, tail=idx+l-1; head<tail; head++, tail--)
                        use += s[head]!=s[tail] ? 1 : 0;
                }
                ret = min(ret, use+behind);
            }
            return dp[idx][k] = ret;
        }
    };
  • 相关阅读:
    猜数字游戏
    Visual Studio Code如何编写运行C、C++
    Git Submodule使用完整教程
    同一客户端多个git账号的配置
    让 Git Bisect 帮助你
    GitHub 风格的 Markdown 语法
    git 命令图解
    图解git中的最常用命令
    Understanding the Bias-Variance Tradeoff
    Seven Techniques for Data Dimensionality Reduction
  • 原文地址:https://www.cnblogs.com/jasonlixuetao/p/11977500.html
Copyright © 2020-2023  润新知