H - 简单dp 例题扩展

Crawling in process... Crawling failed Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Submit Status

Description

A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a program which, given a string, determines the minimal number of characters to be inserted into the string in order to obtain a palindrome.

As an example, by inserting 2 characters, the string "Ab3bd" can be transformed into a palindrome ("dAb3bAd" or "Adb3bdA"). However, inserting fewer than 2 characters does not produce a palindrome.

Input

Your program is to read from standard input. The first line contains one integer: the length of the input string N, 3 <= N <= 5000. The second line contains one string with length N. The string is formed from uppercase letters from 'A' to 'Z', lowercase letters from 'a' to 'z' and digits from '0' to '9'. Uppercase and lowercase letters are to be considered distinct.

Output

Your program is to write to standard output. The first line contains one integer, which is the desired minimal number.

Sample Input

  1. 5
  2. Ab3bd

Sample Output

  1. 2
    题目大意:给你一个字符串,让你往其中插入字符,使其变成回文字符串,问最少需要插入多少字符。
    思路分析:所谓回文字符串,就是正读和倒读一样的,因此可以考虑构造两个字符串,另一个字符串是
    原字符串的逆序串,然后求最长公共子序列长度,那么字符串长度减去最长公共字符串长度就是需要插入
    的字符数,注意dp数组开short,否则会爆内存。
    代码:
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <stack>
    using namespace std;
    const int maxn=5000+100;
    short dp[maxn][maxn];
    int main()
    {
        int n;
        char s1[maxn],s2[maxn];
        scanf("%d",&n);
           cin>>s1;
           for(int i=n-1;i>=0;i--)
            s2[n-i-1]=s1[i];
           memset(dp,0,sizeof(dp));
           for(int i=0;i<n;i++)
           {
               for(int j=0;j<n;j++)
               {
                   if(s1[i]==s2[j])
                   {
                       if(i>=1&&j>=1)
                        dp[i][j]=dp[i-1][j-1]+1;
                       else dp[i][j]=1;
                   }
                   if(s1[i]!=s2[j])
                   {
                       if(i==0&&j==0) dp[0][0]=0;
                       else if(i>=1&&j==0) dp[i][j]=dp[i-1][j];
                       else if(i==0&&j>=1) dp[i][j]=dp[i][j-1];
                       else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
                   }
               }
           }
           cout<<(n-dp[n-1][n-1])<<endl;
        return 0;
    }
    优化:如果开数组dp[maxn][maxn],非常耗内存,如果不用short开就会MLE.但是我们注意到,
    dp[i][j]只与上一层的dp[i-1][j-1]或dp[i-1][j]有关,因此可以采用就地滚动的方法节省
    内存,只需要开一个dp[2][maxn]的数组,同时,字符串在储存的时候也有技巧,推荐从1-n储存,
    这样dp边界处理起来就容易的多。
    代码:
    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <stack>
    using namespace std;
    const int maxn=5000+100;
    const int inf=0xfffffff;
    short dp[2][maxn];//滚动数组
    int main()
    {
        int n;
        char s1[maxn],s2[maxn];
        scanf("%d",&n);
           scanf("%s",s1+1);
           for(int i=n;i>=1;i--)
            s2[n-i+1]=s1[i];
           memset(dp,0,sizeof(dp));
           int ma=-inf;
           for(int i=1;i<=n;i++)
           {
               for(int j=1;j<=n;j++)
               {
                   if(s1[i]==s2[j])
                   {
                        dp[i%2][j]=dp[(i-1)%2][j-1]+1;
                   }
                   if(s1[i]!=s2[j])
                   {
                        dp[i%2][j]=max(dp[(i-1)%2][j],dp[i%2][j-1]);
                   }
                   if(dp[i%2][j]>ma) ma=dp[i%2][j];
               }
           }
           cout<<(n-ma)<<endl;
        return 0;
    }

poj1159 dp(滚动数组优化)的更多相关文章

  1. HDU_1024.MaxSumPlusPlus(基础DP + 滚动数组优化讲解)

    这道题打破了我常规的做题思路,因为这是我刚开始训练DP,感觉这道题目好晕眼呀,emm其实就是感觉自己是真的菜...... 为什么说打破了我的做题思路呢,因为我平时看题解都是在已经AC或者完全不懂的情况 ...

  2. [BZOJ1044][HAOI2008]木棍分割 二分 + 单调队列优化dp + 滚动数组优化dp

    Description 有n根木棍, 第i根木棍的长度为Li,n根木棍依次连结了一起, 总共有n-1个连接处. 现在允许你最多砍断m个连接处, 砍完后n根木棍被分成了很多段,要求满足总长度最大的一段长 ...

  3. LG3004 「USACO2010DEC」Treasure Chest 区间DP+滚动数组优化

    问题描述 LG3004 题解 把拿走的过程反向,看做添加的过程,于是很显然的区间DP模型. 设\(opt_{i,j}\)代表区间\([i,j]\)中Bessie可以获得的最大值,显然有 \[opt_{ ...

  4. 51Nod 1084 矩阵取数问题 V2 双线程DP 滚动数组优化

    基准时间限制:2 秒 空间限制:131072 KB  一个M*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,先从左上走到右下,再从右下走到左上.第1遍时只能向下和向右走,第2遍时只能向 ...

  5. 2014年北京 happy matt friends(dp + 滚动数组优化)

    Happy Matt Friends Time Limit: 6000/6000 MS (Java/Others)    Memory Limit: 510000/510000 K (Java/Oth ...

  6. POJ 3666 Making the Grade (DP滚动数组)

    题意:农夫约翰想修一条尽量平缓的路,路的每一段海拔是A[i],修理后是B[i],花费|A[i] – B[i]|,求最小花费.(数据有问题,代码只是单调递增的情况) #include <stdio ...

  7. Codeforces 712 D. Memory and Scores (DP+滚动数组+前缀和优化)

    题目链接:http://codeforces.com/contest/712/problem/D A初始有一个分数a,B初始有一个分数b,有t轮比赛,每次比赛都可以取[-k, k]之间的数,问你最后A ...

  8. dp,滚动数组优化

    51Nod1084矩阵取数问题 V2 题意: 一个M*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,先从左上走到右下,再从右下走到左上.第1遍时只能向下和向右走,第2遍时只能向上和向左 ...

  9. hdu 3392(滚动数组优化dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3392 Pie Time Limit: 6000/3000 MS (Java/Others)    Me ...

随机推荐

  1. (原)windows8.1上使用opencv for python

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/6204100.html 参考网址: http://www.docs.opencv.org/master/ ...

  2. JS将毫秒转换成时间格式

    JavaScript Date(日期)对象 实例 getTime():返回从 1970 年 1 月 1 日至今的毫秒数. setFullYear(): 设置具体的日期. toUTCString():将 ...

  3. js判断当前操作系统

    function validataOS(){ if(navigator.userAgent.indexOf(“Window”)>0){ return ”Windows”; }else if(na ...

  4. jquery-multiselect在ie6里的一个bug

    在使用jquery-multiselect(一个把下拉框改造成带checkbox的可以多选的控件)时,正常时应该是下面这样:而它在ie6里是下面这样: 其中第一个bug参考‘ie6里png图片不透明’ ...

  5. 关于在transform下的子元素设置fixed无效的困惑

    最近的项目是要实现一个点击显示隐藏边栏的效果,而且需要边栏随着滚动而滚动. 思路简单,不就一个css的动画和一个position为fixed,搞定!但不想,设为fixed的子元素竟然无法fixed,这 ...

  6. 一个基础的CURL类

    /** * 一个基础的CURL类 * * @author Smala */ class curl{ public $ch; public $cookie = '/cookie'; public $rs ...

  7. IE6 png 透明 (三种解决方法)(转来的哦)

    FF和IE7已经直接支持透明的png图了,下面这个主要是解决IE6下透明PNG图片有灰底的 ====================================================== ...

  8. java并发编程_基本模块构建

    读<java并发编程实战>第五章学习记录:该章节主要介绍一些并发编程中一些基本的构建模块.如并发容器和并发工具类(闭锁和栅栏)以及一些需要注意的情况 并发容器 1. ConcurrentH ...

  9. iOS学习之懒加载

    懒加载——也称为延迟加载,即在需要的时候才加载(效率低,占用内存小).所谓懒加载,其实是重写getter方法. 注意:如果是懒加载的话则一定要注意先判断是否已经有了,如果没有那么再去进行实例化 使用懒 ...

  10. tomcat文件夹与文件解析

    今天看到一篇不错的文章,如下: /bin:存放启动和关闭tomcat的脚本文件: /conf:存放tomcat的各种配置文件,比如:server.xml/ server/lib:存放tomcat服务器 ...