您的位置:首页 > 其它

最少回纹切割数(Palindrome Partitioning II)

2014-07-21 21:36 302 查看
题目:给定一个字符串,把这个字符串切割成若干段,使得这些小段都是回纹串,求最少要切几刀(即小段回文串的个数减一)。

分析:先用动态规划法求得任意子串是否是回纹,用str表示字符串,用f[i,j]表示从字符i到字符j组成的子串是否是回纹,

j-i < 2时,即子串只有一个字符或者两个字符时
f[i,j] = str[i] == str[j]
其他情况,
f[i,j] = f[i+1,j-1] && str[i]==str[j]
求得任意子串是否是回纹后,则可以用来下面对最小切分数的求取。
首先我们用dp[i]表示从第一个字符到第i个字符所成子串的最小切分数,我们可以理解,当f[j,i]=true时,
dp[i] = min(dp[j,i] +1) 0<=j<=l。初始条件我们设为dp[0] = -1,
因为j<=i当j==i时f[j,i]必为true,所以上述式子一定成立。

代码如下:

#include <iostream>
#include <string>
#include <vector>
using namespace std;
 
int palindrome2(string str){
    int len = str.length();
    vector<vector<bool>> dp(len,vector<bool>(len));
    for(int i = len-1;i>=0;i--){
       dp[i][i] = true;
       for(int j = i+1;j<len;j++){
           if(j - i < 2)
              dp[i][j] = (str[i] == str[j]);
           else
              dp[i][j] = dp[i+1][j-1]&&(str[i] == str[j]);
       }
    }
    vector<int> mincutDP(len+1);
    mincutDP[0] = -1;
    for(int i = 1;i<=len;i++){
       mincutDP[i] = mincutDP[i-1]+1;
       int curr = mincutDP[i];
       for(int j = 1;j<=i;j++){
           if(dp[j-1][i-1]){
              curr = mincutDP[j-1]+1;
              if(curr < mincutDP[i])
                  mincutDP[i] = curr;
           }
       }
    }
    return mincutDP[len];
}
 
int main()
{
    string str = "abcdc";
    cout<<palindrome2(str)<<endl;
    getchar();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: