leetcode 1278 分割回文串

 time O(n^2*k)  space O(n^2)

class Solution {
public:
    int palindromePartition(string s, int K) {
        //分成两步:第一步递归求将下标【i,j】变为回文子串的最小代价cost(i,j);   
        //cost(i,j)=cost(i+1,j-1)+(s[i]!=s[j]?1:0);
        //第二步:利用cost(i,j)递归求解将0~i分为k个回文子串的最小代价dp(i,k);   
        //dp(i,k)=min{dp(j,k-1)+cost(j+1,i)}  j range from [0,i-1],k range from [2,K];
        //dp(i,1)=cost(0,i);
        int len=s.length();
        vector<vector<int>> cost(len,vector<int>(len,0));
        for(int l=1;l<len;l++){
            for(int i=0;i<len&&(i+l<len);i++){
                int j=i+l;
                cost[i][j]=cost[i+1][j-1]+(s[i]!=s[j]?1:0);
            }
        }
         
        vector<vector<int>> dp(len,vector<int>(K+1,INT_MAX-1024));
        for(int i=0;i<len;i++){
            dp[i][1]=cost[0][i];
            for(int k=2;k<=K;k++){
                for(int j=0;j<i;j++){
                    dp[i][k]=min(dp[i][k],dp[j][k-1]+cost[j+1][i]);
                }
            }
        }
        return dp[len-1][K];
    }
};

参考https://mp.weixin.qq.com/s/Da_6dqSYTa9jOzsh7sD2YQ

首先,完成第一个DP,计算回文子串所需要的cost(i,j),即将【i,j】内的字符串变为回文字符最少需要改变几个字母;

#include <bits/stdc++.h>
using namespace std;
//直接输出cost矩阵
int main()
{
    cout << "Hello World"<<endl;
    string s="abcde";
    int len=s.length();
    vector<vector<int>> cost(len,vector<int>(len,0));

    for(int l=1;l<len;l++){
        for(int i=0;i<len&&(i+l<len);i++){
            int j=i+l;
            cost[i][j]=cost[i+1][j-1]+(s[i]!=s[j]?1:0);
        }
    }
    for(int i=0;i<len;i++){
        for(int j=0;j<len;j++){
            cout<<cost[i][j]<<" ";
        }
        cout<<endl;
    }
    cout<<endl;
    return 0;
}

然后,完成第二个DP,计算dp[i][k] (k from 1 to K, i from 0 to len-1) ;

更新说明:

原文地址:https://www.cnblogs.com/joelwang/p/11990609.html