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) ;
更新说明: