1. 程式人生 > >UVA11584 Partitioning by Palindromes

UVA11584 Partitioning by Palindromes

mes max 回文 判斷 sin pan log turn can

題意:一個字符串(l<1000),問最少能分多少個回文串

題解:dp[i]代表前i個字符串最少的回文串,可以由前面的dp遞推,dp[i] = max(dp[i],dp[i-t]+t);(1<t<=i)這裏是n^2,判斷回文串用Manacher

#include <bits/stdc++.h>
#define maxn 100100
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
char s[maxn], s1[maxn];
int p[2*maxn], dp[maxn];
int
init(){ int j = 2, l=strlen(s); s1[0] = &;s1[1] = #; for(int i=0;i<l;i++){ s1[j++] = s[i]; s1[j++] = #; } s1[j] = 0; return j; } void manacher(char *s){ int id=0,ma=0,mlen=-1; int len = init(); for(int i=0;i<len;i++){
if(i<ma) p[i] = min(p[2*id-i], ma-i); else p[i] = 1; while(s1[i-p[i]] == s1[i+p[i]]) p[i]++; if(i+p[i] > ma){ id = i; ma = i+p[i]; } } } int main(){ int T, l; scanf("%d", &T); while(T--){ scanf("%s
", s); l = strlen(s); manacher(s); for(int i=2;i<=2*l;i+=2){ dp[i] = i/2; for(int j=0;j<i;j+=2){ if(p[(i+j+2)/2]-1 >= (i-j)/2) dp[i] = min(dp[i], dp[j]+1); } } printf("%d\n", dp[l*2]); } return 0; }

UVA11584 Partitioning by Palindromes