• POJ1159:Palindrome【dp】


    题目大意:给出一个字符串,问至少添加多少个字符才能使它成为回文串?

    思路:很明显的方程是:dp[i][j]=min{dp[i+1][j],dp[i][j-1],dp[i+1][j-1](str[i]==str[j]时)}

    dp[i][j]表示第i个字符到第j个字符构造成回文串最少添加的字符,但discuss里说了 这样做会超空间+超时

    观察下这个方程,每次用到的就是那三个子状态,于是适当的改变方程的形式:

    dp[i][j]表示第i个字符开始长度为j的子串构成的字符串最少需要添加的字符,于是方程变成了dp[i][j]=min{dp[i+1][j-1],dp[i][j-1],dp[i+1][j-2](str[i]==str[j]时)},递推时只需储存长度为j-1和j-2的数据就能推出长度为j的数据,利用指针改变下三个数组的顺序即可。于是空间问题顺利解决

    //poj1159

    #include<cstdio>

    #include<string.h>

    #include<iostream>

    using namespace std;

    const int maxn=5009;

    int min(int a ,int b)

    {

       if(a>b)return b;else return a;

    }

    int main()

    {

       int n;

       char str[maxn];

       scanf("%d %s",&n,str);

       int a[maxn]={0},b[maxn]={0},c[maxn]={0};

       int *ans=a,*f=b,*ff=c,*temp;

       for(int k=1;k<=n;k++)

        {

           for(int i=1;i<=n-k+1;i++)

           {

               ans[i]=min(f[i],f[i+1])+1;

               if (str[i-1]==str[i+k-2])ans[i]=min(ans[i],ff[i+1]);

           }

           temp=ff;ff=f;f=ans;ans=temp;

        }

       printf("%d ",f[1]);

       return 0;

    }

  • 相关阅读:
    浏览器如何减少 reflow/repaint
    caller和callee的区别
    正则表达式中的2和1和3不仅分组还占位
    正则分组和捕获
    Javascript之BOM与DOM讲解
    Ubuntu14.04(nginx+php+mysql+vsftp)配置安装流程
    JS的类型转换
    typeof 和 instanceof
    ios对new Date() 的兼容问题
    module.exports 和 export default
  • 原文地址:https://www.cnblogs.com/philippica/p/4006970.html
Copyright © 2020-2023  润新知