• hdu1513 pku 1159Palindrome


    这倆道是一样的题目,题意就是将一个字符串转变为回文串的最少添加数

    有俩种方法:

    1.求正串和反串的最长公共子序列,再用原先串的长度相减即可;

    2.c (i,j)表示将子串aiai+1…aj变成回文词的最小添加字符数。则这此问题就是要求c(1,n)

    c(i,j)满足如下递推关系:
    从代码可以看出,俩种方法的效率想差很大
    第一种方法
    #include<iostream>
    #include
    <string>
    #include
    <algorithm>
    using namespace std;
    int main()
    {
    char s1[5010],s2[5010];
    int s[2][5010],l1,l2;
    while(scanf("%d %s",&l1,s1)==2)
    {
    l2
    =0;
    for(int i=l1-1;i>=0;i--)
    s2[l2
    ++]=s1[i];
    memset(s,
    0,sizeof(s));
    for(int i=0;i<l1;i++)
    {
    for(int j=0;j<l2;j++)
    {
    if(s1[i]==s2[j])
    s[(i
    +1)%2][j+1]=s[i%2][j]+1;
    else
    s[(i
    +1)%2][j+1]=s[i%2][j+1]>s[(i+1)%2][j]?s[i%2][j+1]:s[(i+1)%2][j];
    }
    }

    printf(
    "%d\n",l1-s[l1%2][l2]);
    }
    return 0;
    }
    第二种方法
    #include<iostream>
    #include
    <string.h>
    using namespace std;
    char cc[5001];
    int dp[2][5001];
    int n;
    inline
    int Min(int x,int y)
    {
    return x>y?y:x;
    }
    int main()
    {
    while(scanf("%d",&n)!=EOF)
    {
    scanf(
    "%s",cc+1);
    memset(dp,
    0,sizeof(dp));
    for(int i=n-1;i>=1;i--)
    for(int j=i+1;j<=n;j++)
    {
    if(cc[i]==cc[j])
    dp[i
    %2][j]=dp[(i+1)%2][j-1];
    else
    dp[i
    %2][j]=1+Min(dp[(i+1)%2][j],dp[i%2][j-1]);
    }
    printf(
    "%d\n",dp[1][n]);
    }
    return 0;
    }

  • 相关阅读:
    注册算法入门
    call传参之通过堆栈
    winhex注意
    输入字符串长度
    integer promotion
    网页flash兼容浏览器代码
    逆向工程——注册篇
    esp定律的一点说明
    base64
    意外
  • 原文地址:https://www.cnblogs.com/nanke/p/2147661.html
Copyright © 2020-2023  润新知