- 思路:
这种分割字符串的题目往往都是这样设计DP的阶段的:考虑前缀 [ 0 , i ] [0,i] [0,i]分割成 k k k段的花费。 - DP 方程: d p [ k ] [ i ] = m i n ( d p [ k − 1 ] [ j ] + c o s t [ j + 1 , i ] ) ( j < i ) dp[k][i]=min(dp[k-1][j]+cost[j+1,i]) (j<i) dp[k][i]=min(dp[k−1][j]+cost[j+1,i])(j<i)
考虑在 c o s t [ l , r ] cost[l,r] cost[l,r]可以预处理出。
时间复杂度: O ( n 3 ) O(n^3) O(n3)
/*
dp[k][i] = min(dp[k][i],dp[k-1][j]+cost[j+1,i]);
*/
class Solution {
public:
int dp[110][110],cost[110][110] = {
0};
int palindromePartition(string s, int K) {
memset(dp,0x3f,sizeof(dp));
int n = s.size();
for(int i=0;i<n;i++)
for(int j=i+1;j<n;j++)
cost[i][j] = get_cost(s,i,j);
for(int i=0;i<n;i++)
dp[1][i] = cost[0][i];
for(int k=2;k<=K;k++)
for(int i=k-1;i<n;i++)
for(int j=k-2;j<i;j++)
dp[k][i]= min(dp[k][i],dp[k-1][j]+cost[j+1][i]);
return dp[K][n-1];
}
int get_cost(const string& s,int l,int r){
int res = 0, i = l, j = r;
while(i<j){
if(s[i]!=s[j]){
res++;
}
i++;
j--;
}
return res;
}
};
- 优化:
- 空间上,可以用滚动数组去优化 d p [ ] [ ] dp[][] dp[][]到一维。
- 时间上, c o s t [ i ] [ j ] cost[i][j] cost[i][j]也可以使用dp进行优化。
c o s t [ l ] [ r ] = c o s r [ l + 1 ] [ r − 1 ] + ( s [ l ] ! = s [ r ] ) cost[l][r] = cosr[l+1][r-1]+(s[l]!=s[r]) cost[l][r]=cosr[l+1][r−1]+(s[l]!=s[r])