poj 1159 Palindrome(lcs类似dp)

来源:互联网 发布:qt5编程入门 pdf 编辑:程序博客网 时间:2024/06/09 07:14

题意:问一个字符串最少插入多少个字符可以将其变成回文串。

思路:

f(i, k) 为 从i开始长度为k 的字串变成回文串最少需要插入字符数。

看见discuss明白了这个口以看作 原串长-正逆串lcs。。

不过开二维数组会mle, 不过貌似空间减半就可以了,所以直接有人用压缩矩阵或者改用short。。

我用f1,f2分别保存上个和上上个状态,空间消耗5000*2。。

//#include<bits/stdc++.h>#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <vector>#include <queue>#include <stack>#include <cassert>#include <algorithm>#include <cmath>#include <climits>#include <set>#include <map>using namespace std;#define SPEED_UP iostream::sync_with_stdio(false);#define FIXED_FLOAT cout.setf(ios::fixed, ios::floatfield);#define rep(i, s, t) for(int (i)=(s);(i)<=(t);++(i))#define urep(i, s, t) for(int (i)=(s);(i)>=(t);--(i))typedef long long LL;const int Maxn = 5000;const int inf = INT_MAX/2;char a[Maxn+5];int f1[Maxn+5], f2[Maxn+5], len;int f(int l, int r) {    if (l >= r) return 0;    if (r-l+1 == len-2) return f2[l];    return f1[l];}int main() {#ifndef ONLINE_JUDGE    freopen("input.in", "r", stdin);#endif    SPEED_UP    int n;    cin >> n >> a;    rep(k, 2, n)        rep(i, 0, n-k) {            int j = i+k-1, tmp = inf;            len = k;            tmp = min(f(i+1, j), f(i, j-1))+1;            if (a[i] == a[j])                tmp = min(tmp, f(i+1, j-1));            else                tmp = min(tmp, f(i+1, j-1)+2);            f2[i] = f1[i];            f1[i] = tmp;            //cout << "f(" << i << ", " << j << ") " << f[i][j] << endl;        }    cout << f(0, n-1) << endl;    return 0;}


0 0
原创粉丝点击