码迷,mamicode.com
首页 > 其他好文 > 详细

Palindrome Partitioning LightOJ - 1044(回文串最小分割数,O(n^2)预处理子串是否回文)

时间:2017-10-27 21:28:20      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:art   use   tar   一个   .net   print   回文串   ring   target   

题意:将一个字符串分割成最少的字符串,使得分割出的每个字符串都是回文串。输出最小的分割数。

方法(自己的):先O(n^2)(用某个点或某个空区间开始,每次向左右扩展各一个的方法)处理出所有子串是否回文。然后常规区间dp,ans[i][j]表示i到j的子串的最小划分数。如果i到j的子串本身为回文串,那么ans[i][j]为1,否则枚举所有方案将i到j划分为两个区间,取所有两个区间结果之和的最小值。

方法(其他,大概就是压了一下空间,压了一下时间的常数):http://blog.csdn.net/l123012013048/article/details/49475845

解题思路:用dp[i]表示前i个字符划分成回文串,需要划分成多少个部分 
接着枚举j,如果[i,j]回文,那么dp[i] = min(dp[i], dp[j - 1] + 1)

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 bool ok[1010][1010];
 6 char s[1010];
 7 int T,TT,len,ans[1010][1010];
 8 int get(int l,int r)
 9 {
10     if(ans[l][r])    return ans[l][r];
11     if(l==r)    return 1;
12     if(ok[l][r])    return ans[l][r]=1;
13     int anss=0x3f3f3f3f,i;
14     for(i=l;i<r;i++)
15         if(ok[l][i])
16             anss=min(anss,get(i+1,r)+1);
17     return ans[l][r]=anss;
18 }
19 int main()
20 {
21     int i,l,r;
22     bool now;
23     scanf("%d",&T);
24     for(TT=1;TT<=T;TT++)
25     {
26         scanf("%s",s+1);
27         len=strlen(s+1);
28         memset(ans,0,sizeof(ans));
29         for(i=1;i<=len;i++)
30             for(l=i,r=i,now=1;l>=1&&r<=len;l--,r++)
31             {
32                 if(s[l]!=s[r])    now=0;
33                 ok[l][r]=now;
34             }
35         for(i=1;i<len;i++)
36             for(l=i,r=i+1,now=1;l>=1&&r<=len;l--,r++)
37             {
38                 if(s[l]!=s[r])    now=0;
39                 ok[l][r]=now;
40             }
41         printf("Case %d: %d\n",TT,get(1,len));
42     }
43     return 0;
44 }

Palindrome Partitioning LightOJ - 1044(回文串最小分割数,O(n^2)预处理子串是否回文)

标签:art   use   tar   一个   .net   print   回文串   ring   target   

原文地址:http://www.cnblogs.com/hehe54321/p/loj-1044.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!