传送门

 

题意  

UVA 11584 "Partitioning by Palindromes"(DP+Manacher)

思路一

  定义 dp[i] 表示 0~i 的最少划分数;

  首先,用马拉车算法求解出回文半径数组;

  对于第 i 个字符 si,遍历 j (0 ≤ j < i),判断以 j 为回文中心的最大回文串是否包含 si

  如果包含,dp[ i ]=min{dp[ i ],dp[2*j-i-1]+1};

Code

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e3+50;
 4 
 5 char t[maxn];
 6 int r[maxn<<1];
 7 
 8 struct Manacher
 9 {
10     char s[maxn<<1];
11     void Init(char *ss,int len)
12     {
13         int index=0;
14         s[index++]='#';
15         for(int i=0;i < len;++i)
16         {
17             s[index++]=ss[i];
18             s[index++]='#';
19         }
20         s[index]='\0';
21     }
22     void mana(char *ss)
23     {
24         Init(ss,strlen(ss));
25         int len=strlen(s);
26         int R=-1;
27         int C;
28         for(int i=0;i < len;++i)
29         {
30             r[i]=R > i ? min(R-i+1,r[2*C-i]):1;
31             for(;i-r[i] >= 0 && i+r[i] < len && s[i-r[i]] == s[i+r[i]];r[i]++);
32             if(i+r[i] > R)
33             {
34                 R=i+r[i]-1;
35                 C=i;
36             }
37         }
38     }
39 }_mana;
40 
41 int dp[maxn];
42 int Solve()
43 {
44     _mana.mana(t);
45 
46     dp[0]=1;
47     int len=strlen(t);
48     for(int i=1;i < len;++i)
49     {
50         dp[i]=dp[i-1]+1;
51         for(int j=0;j <= 2*i;++j)
52         {
53             
54             ///t中的第i个字符在预处理后的s数组中的位置为2*i+1
55             ///因为可能由偶回文的情况,所以需要用到'#'
56             ///直接判断在s数组中j的对应的最大回文j+r[j]是否包含2*i+1
57             ///如果包含,再找到2*i+1以j为中心的对称点2*j-(2*i+1)
58             ///判断2*j-(2*i+1)对应于t中的位置的前一个位置(2*j-(2*i+1))/2-1是否在[0,len-1]范围内
59             ///如果在,更新dp[i]
60             int cur=j+r[j];
61             int index=(2*j-2*i-1)/2-1;
62             if(2*i+1 < cur)
63                 dp[i]=min(dp[i],1+(index >= 0 ? dp[index]:0));
64         }
65     }
66     return dp[len-1];
67 }
68 int main()
69 {
70 //    freopen("C:\\Users\\hyacinthLJP\\Desktop\\in&&out\\contest","r",stdin);
71     int test;
72     scanf("%d",&test);
73     while(test--)
74     {
75         scanf("%s",t);
76         printf("%d\n",Solve());
77     }
78     return 0;
79 }
View Code 

相关文章: