zoukankan      html  css  js  c++  java
  • 回文词,区间dp初探

    回文词

    给出一个长度不超过5000的串s ,给s 添加尽量少的字母,使它变成一个回文词,即首尾对称的词。例如cbabd 可以添加两个字符变成dcbabcd, 它是首尾对称的。
    输入:
    第一行一个整数表示,串的长度。
    第二行一个串。
    输出:
    一个数字,最少要加的字母数。
    样例:
    输入:
    3
    abb
    输出:
    1

    网上的代码多为lcs,然而我觉得还有一种解法。

    dp(i,j)将i——j这一段区间变成回文词的最小代价。

    如果i==j,那么dp(i,j)=dp(i+1,j-1)+1;(这是特殊情况)

    一般情况:

    无论如何,我们都可以加一个与i,j配对。

    所以dp(i,j)=min(dp(i,j-1)+1,dp(i+1,j)+1);

    所以时间复杂度为n^2

    空间复杂度为n^2

    可以通过:下面是代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define N 5000+10
    #define INF 999999
    using namespace std;
    int len;
    char s[N];
    int f[N][N];
    int dp(int i,int j)
    {
        if(i==j)return f[i][j]=0;
        if(j-i==1)
        {
            if(s[i]==s[j])return f[i][j]=0;
            else return f[i][j]=1;
        }
        if(f[i][j])return f[i][j];
        if(s[i]==s[j]) return f[i][j]=dp(i+1,j-1);
        else  return f[i][j]=min(dp(i+1,j)+1,dp(i,j-1)+1);
    }
    int main()
    {
        scanf("%d
    ",&len);
        for(int i=1;i<=len;i++)s[i]=getchar();
        memset(f,INF,sizeof(f));
        printf("%d",dp(1,len));
        return 0;
    }

    当然,空间还可以通过滚动数组优化到o(n)

  • 相关阅读:
    Java中的访问控制权限
    [Java IO]05_JSON操作
    redis 系列22 复制Replication (下)
    redis 系列21 复制Replication (上)
    redis 系列20 服务器下
    redis 系列20 服务器上
    redis 系列19 客户端
    redis 系列18 事件
    redis 系列17 持久化 AOF
    redis 系列16 持久化 RDB
  • 原文地址:https://www.cnblogs.com/star-eternal/p/7574848.html
Copyright © 2011-2022 走看看