POJ 1159 回文LCS滚动数组优化

详细解题报告可以看这个PPT

这题如果是直接开int 5000 * 5000  的空间肯定会MLE,优化方法是采用滚动数组。

原LCS转移方程 :

dp[i][j] = dp[i - 1][j] + dp[i][j  -1]

因为 dp[i][j] 只依赖于 dp[i - 1][j] 和 dp[i][j - 1]

所以可以采用滚动数组如下:

dp[i % 2][j] = dp[(i - 1) % 2][j] + dp[i % 2][j - 1]

可以实现节省空间的方法

答案存储在 dp[n % 2][n] 中

source code:

//#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define ll long long
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))

using namespace std;

const int INF  = 0x3f3f3f3f;
const int MAXN = 500;

int dp[2][5005];

int main(){
    int i, j, t, k, n, m;
    string str1, str2;
    while(EOF != scanf("%d",&n)){
        cin >> str1;
        str2 = str1;
        reverse(str1.begin(), str1.end());
        memset(dp, 0, sizeof(dp));
        for(i = 1; i <= n; ++i){
            for(j = 1; j <= n; ++j){
                if(str1[i - 1] == str2[j - 1]){
                    dp[i % 2][j] = max(dp[i % 2][j], dp[(i - 1) % 2][j - 1] + 1);
                }
                else{
                    dp[i % 2][j] = max(dp[(i - 1) % 2][j], dp[i % 2][j - 1]);
                }
            }
        }
        cout << n - dp[n % 2][n] << endl;   //answer = X.length() - LCS(X, Y)
    }
    return 0;
}
时间: 2024-12-28 08:33:53

POJ 1159 回文LCS滚动数组优化的相关文章

HDU 1513 &amp;&amp; POJ 1159 Palindrome (DP+LCS+滚动数组)

题意:给定一个字符串,让你把它变成回文串,求添加最少的字符数. 析:动态规划是很明显的,就是没有了现思路,还是问的别人才知道,哦,原来要么写,既然是回文串, 那么最后正反都得是一样的,所以我们就正反求LCS,这样公共的就求出来了,那么再用总数减掉这个LCS, 那么剩下的肯定就是没有配对的了,就得必须加上了. 思路有了,这里又出现一个问题,这个求LCS,要用的空间复杂度太大了,MLE了...有了思路,还是过不了, 这个题应该用滚动数组来做,我想想在求LCS时,第一维我们只用到了i-1和i,所以呢,

hdu 1513 添最少字回文 (Lcs 滚动数组)

http://blog.csdn.net/ice_crazy/article/details/8244639 这里5000*5000超出内存,所以需要用滚动数组: 用一个now表示当前的结果,pre表示前一个的结果,不断滚动即可 #include <iostream> #include <string> #include <cstring> #include <cstdlib> #include <cstdio> #include <cma

POJ 1159-Palindrome(dp_回文串+滚动数组)

Palindrome 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 wr

POJ 1159 Palindrome(lcs加滚动数组)

Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 52350   Accepted: 18041 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

poj 1159 Palindrome lcs+滚动数组

点击打开链接题目链接 Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 52910   Accepted: 18248 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

HDU - 1024 Max Sum Plus Plus 滚动数组优化

给定n个数字,求其中m段的最大值(段与段之间不用连续,但是一段中要连续) 例如:2 5 1 -2 2 3 -1五个数字中选2个,选择1和2 3这两段. dp[i][j]从前j个数字中选择i段,然后根据第j个数字是否独立成一段,可以写出 状态转移方程:dp[i][j]=max(dp[i][j-1]+num[j],max(dp[i-1][k])+num[j]) 这里的max(dp[i-1][k])代表的拥有i-1段时的最大值,然后再加上num[j]独立成的一段. 但是题目中没有给出m的取值范围,有可

HDU - 1024 Max Sum Plus Plus(dp+滚动数组优化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1024 题意:给定n个数字,求其中m段的最大值(段与段之间不用连续,但是一段中要连续) 例如:2 5 1 -2 2 3 -1五个数字中选2个,选择1和2 3这两段. 题解:dp[i][j]从前j个数字中选择i段,然后根据第j个数字是否独立成一段,可以写出 状态转移方程:dp[i][j]=max(dp[i][j-1]+num[j],max(dp[i-1][k])+num[j]) 这里的max(dp[i-

POJ 1159 Palindrome(字符串变回文:LCS)

http://poj.org/problem?id=1159 题意: 给你一个字符串, 问你做少需要在该字符串中插入几个字符能是的它变成一个回文串. 分析: 首先把原字符串和它的逆串进行匹配, 找出最长公共子序列. 那么最长公共子序列的字符串肯定是一个回文串. 所以原串剩下的部分是不构成回文的. 我们只需要添加剩下部分的字符到对应位置, 原串自然就变成了一个回文. 所以本题的解为: n 减去 (原串与逆串的LCS长度). 令dp[i][j]==x表示串A的前i个字符与串B的前j个字符的子串的最长

LCS(滚动数组) POJ 1159 Palindrome

题目传送门 1 /* 2 LCS裸题:长度减去最大相同长度就是要插入的个数 3 dp数组二维都开5000的话就会超内存,这里就用到了滚动数组, 4 因为在LCS的计算中,i的变化只相差1,所以可以通过对2取余来进行滚动:) 5 */ 6 #include <cstdio> 7 #include <iostream> 8 #include <cstring> 9 #include <algorithm> 10 #include <string> 1