给出一字符串,将其分割成一系列回文串,子串数量应尽可能的少。
由于昨天刚做了一个类似的题,看完题的第一思路就是枚举区间,时间复杂度o(n^3),妥妥的TLE了。然后开始想各种优化,均无果。倒是顺便看了一下四边形不等式优化。
然后又换了一种思路时间复杂度降到了o(n^2) 。幸好大部分代码还能用,数组的下标运算还错了一次. . . .
if(Is_Palindrome( i , j ) )
ans[ j ] = min(ans[ j ] , ans[ i -1]+1);
ans[ i ] 表示从1 到 i 的最优方案。
#include <iostream> #include <algorithm> #include <cstdlib> #include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <stack> #pragma comment(linker, "/STACK:1024000000"); #define LL long long int #define ULL unsigned long long int #define _LL __int64 #define INF 0x3f3f3f3f #define Mod 1000000009 using namespace std; char s[4010]; bool dp[4001][4001]; int ans[4010]; int di[4010]; void Output(int l) { if(l == 0) return ; Output(di[l]); if(di[l] != 0) printf(" "); for(int i = di[l]+1;i <= l; ++i) { printf("%c",s[i]); } } int main() { int l,i,j,h,e; scanf("%s",s+1); l = strlen(s+1); memset(dp,false,sizeof(dp)); for(i = 1;i <= l; ++i) { dp[i][i] = true; h = i-1; e = i+1; while(1 <= h && e <= l && s[h] == s[e]) { dp[h][e] = true; h--,e++; } h = i,e = i+1; while(1 <= h && e <= l && s[h] == s[e]) { dp[h][e] = true; h--,e++; } } memset(ans,INF,sizeof(ans)); ans[0] = 0; di[1] = 0; for(i = 1;i <= l; ++i) { for(j = i;j >= 1; --j) { if(dp[j][i]) { if(ans[i] > ans[j-1]+1) { ans[i] = ans[j-1]+1; di[i] = j-1; } } } } printf("%d\n",ans[l]); Output(l); puts(""); return 0; }
URAL 1635. Mnemonics and Palindromes,布布扣,bubuko.com
URAL 1635. Mnemonics and Palindromes
原文:http://blog.csdn.net/zmx354/article/details/20078995