您的位置:首页 > 其它

URAL 1635. Mnemonics and Palindromes

2014-02-27 22:50 169 查看
给出一字符串,将其分割成一系列回文串,子串数量应尽可能的少。

由于昨天刚做了一个类似的题,看完题的第一思路就是枚举区间,时间复杂度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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: