区间dp-Palindrome

Palindrome

题意:给一个字符串,问最少加上多少个字符,可以使这个字符串成为回文串

思路一、直接dp(会爆内存)
dp[i][j]表示区间[i,j]之间有最少需要加上多少个字符
状态转移方程:如果s[i] = s[j], 则dp[i][j] = dp[i + 1][j - 1];
如果s[i] != s[j], 则dp[i][j] = max(dp[i + 1][j], dp[i][ j - 1]) + 1;

思路二、记录字符串的reverse和该字符串的最长公共子序列长度ans是多少,
长度n - ans就是最终结果
注意,需要使用滚动数组优化

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

const int N = 5005;
int n;
string st1, st2;
int dp[2][N];
int ans;

signed main(){
    cin >> n;
    cin >> st1;
    st2 = st1;
    reverse(st2.begin(), st2.end());
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= n; j++){
            if(st1[i - 1] == st2[j - 1]){
                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]);
            }
            ans = max(ans, dp[i % 2][j]);
        }
    }
    cout << n - ans << endl;
    return 0;
}
posted @ 2022-11-19 20:29  风归去  阅读(21)  评论(0)    收藏  举报