给定一个字符串,切分该字符串,使得到的子串都是回文字符串,计算最少的切分次数。

给定一个字符串,计算出将该字符串切分成若干个回文子串所需的最少切分次数。

直接计算一个字符串的切分次数,很难,可以试着缩小问题规模,从而发现规律。

假设给出的字符串可以用ps[0->iend]表示,ps[0],ps[1],...,ps[iend]都是字符。

min_count(i,j),表示将字符串ps[i->j]切分成若干回文字符串所需的最少切分次数。

min_count(i,i)=0;

min_count(i,i+1)=(ps[i]!=ps[i+1]?1:0);

当j>=i+2时,如果ps[i->j]是回文字符串,则min_count(i,j)=0;

如果ps[i->j]不是回文字符串,能否通过子问题的解计算min_count(i,j);这就引发了两个新问题:(1)、原问题的解与子问题的解之间的关系。(2)、怎样判断ps[i->j]是不是一个回文字符串。

对于问题(1),若ps[i->j]最后在t处切分得到了若干回文字符串,使得切分ps[i->j]所需的次数最少,则切分ps[i->t]和ps[(t+1)->j]的次数也应该是最少的,用反证法容易证明。这样就可以考虑用动态规划法求解。其中t=i,(i+1),...,(j-1)。

总之,min_count(i,j)=Min{min_count(i,t),min_count(t+1,j)}+1。

其中,j>=i+2;t=i,(i+1),...,(j-1)。

对于问题(2),若ps[i->j]是回文字符串,则ps[(i+1)->(j-1)]必是回文字符串,而且ps[i]==ps[j]。反之已成立。

用is_palindrome(i,j)表示ps[i->j]是否是回文字符串。

is_palindrome(i,j)=true,若ps[i->j]是回文字符串;

is_palindrome(i,j)=false,若ps[i->j]不是回文字符串。

is_palindrome(i,i)=true;

is_palindrome(i,i+1)=(ps[i]==ps[i+1]?true:false);

当j>=i+2时,

is_palindrome(i,j)=(is_palindrome(i+1,j-1)?(ps[i]==ps[j]?true:false):false);

综上可知:

(1)、min_count(i,i)=0

(2)、min_count(i,i+1)=(ps[i]!=ps[i+1]?1:0)

(3)、若j>=i+2,如果is_palindrome(i,j)=true,则min_count(i,j)=0;

如果is_palindrome(i,j)=false,则min_count(i,j)=Min{min_count(i,t),min_count(t+1,j)}+1;其中t=i,(i+1),...,(j-1)。

源码在github上(https://github.com/wjt2015/palindrome_cut)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值