题目:
分析:看完题稍稍想了一下,就是dp,看了一下确实dp。
我的dp思路:A【i】【j】表示从i到j需要多少次变成回文,给一个记忆化的搜索。但是又超时了。
代码:
class Solution {
public:
bool judge(string s,int x,int y)
{
while(x<y)
{
if(s[x]!=s[y]) return 0;
x++;
y--;
}
return 1;
}
vector<vector<int> > vv;
int f(string s,int x,int y)
{
if(vv[x][y]!=-1) return vv[x][y];
if(judge(s,x,y)) return vv[x][y]=0;
int minn=1<<30;
for(int i=x;i<y;i++)
{
minn=min(minn,1+f(s,x,i)+f(s,i+1,y));
}
return vv[x][y]=minn;
}
int minCut(string s) {
if(judge(s,0,s.length()-1)) return 0;
vector<int> v(s.length(),-1);
for(int i=0;i<s.length();i++) vv.push_back(v);
int minn=1<<30;
for(int i=0;i<s.length()-1;i++)
{
minn=min(minn,1+f(s,0,i)+f(s,i+1,s.length()-1));
}
return minn;
}
};
看题解,自己dp设计的太过暴力。
中心扩展法:
dp【i】表示的是到i元素为止,最小的分割次数。
class Solution {
public:
vector<int> dp;
void f(string s,int x,int y)
{
while(x>=0 && y<s.size() && s[x]==s[y])
{
dp[y]=min(dp[y],(x==0?-1:dp[x-1])+1);
x--;
y++;
}
}
int minCut(string s) {
for(int i=0;i<s.size();i++)
{
dp.push_back(i);
//初始化最大的切割次数。
}
for(int i=0;i<s.size();i++)
{
f(s,i,i);//奇数长度的串以单个为中心
f(s,i,i+1);//偶数长度的串以两个为中心
}
return dp[s.size()-1];
}
};