动态规划——划分为回文串

来源:互联网 发布:淘宝店铺招牌图片童装 编辑:程序博客网 时间:2024/06/06 03:16

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2631


题意:

输入一个字符串,问最少可以将它划分成多少个回文串。


思路:

可以设置dp[i]为从第一个字符到第i个字符之间最少可以划分的回文串,然后设1<=j<=i,如果s[j+1]~s[i]是回文串那么dp[i]=min(dp[j]+1)


O(n的三次方)写法,20ms

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <queue>#include <algorithm>#include <vector>#include <stack>#define INF 0x3f3f3f3f#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int maxn=1010;char s[maxn];int dp[maxn];int len;bool check(int a, int b){    int left=a, right=b;    while(a<b)    {        if(s[a]!=s[b])            return false;        a++; b--;    }    return true;}int main(){    int t;    scanf("%d", &t);    while(t--)    {        scanf("%s", s+1);        len=strlen(s+1);        memset(dp, 0, sizeof(dp));        for(int i=1; i<=len; i++)        {            dp[i]=i+1;            for(int j=1; j<=i; j++)                if(check(j, i))                    dp[i]=min(dp[i], dp[j-1]+1);        }        printf("%d\n", dp[len]);    }    return 0;}


O(n方)写法,事先打表将回文串标记,30ms。。。

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <cmath>#include <queue>#include <algorithm>#include <vector>#include <stack>#define INF 0x3f3f3f3f#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int maxn=1010;bool wtf[maxn][maxn];int dp[maxn];char s[maxn];int len;void init(){    memset(wtf, 0, sizeof(wtf));    for(int i=1; i<=len; i++)        wtf[1][i]=true;    if(len==1)        return;    for(int i=1; i<len; i++)        if(s[i]==s[i+1])            wtf[2][i]=true;    for(int i=3; i<=len; i++)        for(int j=1; j<=len-i+1; j++)            if(s[j]==s[j+i-1]&&wtf[i-2][j+1])                wtf[i][j]=true;}int main(){    int t;    scanf("%d", &t);    while(t--)    {        scanf("%s", s+1);        len=strlen(s+1);        init();        for(int i=1; i<=len; i++)            dp[i]=INF;        dp[0]=0;        for(int i=1; i<=len; i++)        {            for(int j=1; j<=i; j++)                if(wtf[j][i-j+1])                    dp[i]=min(dp[i], dp[i-j]+1);        }        printf("%d\n", dp[len]);    }    return 0;}


估计是数据比较弱,导致O(n方)的写法比O(n的三次方)要慢。。。

原创粉丝点击