最少回纹切割数(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();
}
分析:先用动态规划法求得任意子串是否是回纹,用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();
}
相关文章推荐
- LeetCode | Palindrome Partitioning II(最少切割次数将一个子串划分成回文子串)
- palindrome-partitioning I&II——回文切割、深度遍历
- DP17 最少回文切割次数 Palindrome Partitioning @geeksforgeeks
- 132. Palindrome Partitioning II
- leetcode@ [131/132] Palindrome Partitioning & Palindrome Partitioning II
- [LeetCode] Palindrome Partitioning II (DP)
- #108 Palindrome Partitioning II
- Palindrome Partitioning II
- Palindrome Partitioning II
- LeetCode - Palindrome Partitioning II
- [Leetcode]Palindrome Partitioning II
- Palindrome Partitioning II
- leetcode Palindrome Partitioning I II
- leetcode之 Palindrome Partitioning I&II
- LeetCode 132 Palindrome Partitioning II
- leetcode Palindrome Partitioning II
- Palindrome Partitioning II
- Palindrome Partitioning II
- palindrome-partitioning-ii
- 132. Palindrome Partitioning II