谨遵学长教导,开始刷算法题,从leetcode开始做起。可惜第一次就碰到了两个dp的问题Palindrome Partitioning II。。。第一次搞了半天,感觉像是可以建模为最短路径问题,思路不清晰,乱写竟然通过了judge small,在judge large的时候,最后一个测试例子没有通过,显示超时。不懂为什么,后来google了一下,发现原来是判断是不是回文也要用dp,艾。。后来就没有再管了。今天又重新写了,也做了写注释,感觉思路清晰多了,测试,全部通过。
题目如下:
Given a string s, partition s such that every substring of the partition is a palindrome.
Return the minimum cuts needed for a palindrome partitioning of s.
For example, given s = "aab"
,
Return 1
since the palindrome partitioning ["aa","b"]
could be produced using 1 cut.
int minCut(string s)
{
/*
在s的len个字符之间放len-1个木板,并且在两端个放一个,这样就有len+1个木板
*/
int len=s.length();
int BIG=2*len;
int num_line=len+1;
//表明两个木板之间substr是否为回文,如果有则代表它两端的木板可以直接相连,
//否则,代表它两端的木板必须通过其他木板相连,也就是不相连
//将这些木板作为节点,上面的连接关系作为边,建立图
vector<int> isPalindrome(num_line*num_line);
/*
if s[i]==s[j]
f(i,j)=f(i+1,j-1)
else
f(i,j)=0
*/
for(int l=1;l<=len;l++)//两个木板之间有多少个字符
{
for (int i=0;i+l<num_line;i++)//从第0个木板开始,i+l为木板的序号
{
if (l==1)
{
isPalindrome[i*num_line+(i+l)]=1;
}
else if(l==2)
{
if (s[i]==s[i+l-1])
isPalindrome[i*num_line+(i+l)]=1;
else
isPalindrome[i*num_line+(i+l)]=BIG;
}
else
{
if (s[i]==s[i+l-1])
isPalindrome[i*num_line+(i+l)]=isPalindrome[(i+1)*num_line+(i+l-1)];
else
isPalindrome[i*num_line+(i+l)]=BIG;
}
}
}
/*
找第0个木板与最后一个木板之间的最短距离
*/
vector<int> dist(num_line);
vector<bool> labeled(num_line);
for(int i=0;i<num_line;i++)
{
dist[i]=BIG;
labeled[i]=false;
}
dist[0]=0;
labeled[0]=true;
int current_line=0;
for(int i=1;i<num_line;i++)
{
for(int d=current_line+1;d<num_line;d++)//对所有的相邻(在图中)的木板
{
if(!labeled[d])
{
if (dist[current_line]+isPalindrome[current_line*num_line+d]<dist[d])
{
dist[d]=dist[current_line]+isPalindrome[current_line*num_line+d];
}
}
}
int mindist=BIG;
int minindex=-1;
for(int i=0;i<num_line;i++)
{
if(!labeled[i])
{
if(mindist>dist[i])
{
minindex=i;
mindist=dist[i];
}
}
}
current_line=minindex;
labeled[minindex]=true;
}
return dist[num_line-1]-1;
}