区间dp

Posted on 2023-03-02 17:48  lyc2002  阅读(12)  评论(0编辑  收藏  举报

[acwing]1222.密码脱落

/*
    有多少个前后不配对的字符,就说明脱落了多少个,即总长度减去回文子序列的长度

    dp[i][j] 表示 str[i, j] 的最长回文子序列的长度
    
    如果 str[i] == str[j],dp[i][j] = dp[i + 1][j - 1] + 2
    否则,dp[i][j] = max(dp[i][j - 1], dp[i + 1][j])
    
    对于区间问题,一般先遍历区间长度 len[1, n],再遍历左端点 i[0, n - 1]
    
    无需初始化(或初始化 len = 1 的情况,len 从 2 开始)
    
    dp[0][n - 1]
*/
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1010;

char str[N];
int dp[N][N];

int main()
{
    scanf("%s", str);
    
    int n = strlen(str);
    
    for (int len = 1; len <= n; len++)
        for (int i = 0; i + len - 1 < n; i++) {
            int j = i + len - 1;
            if (len == 1) dp[i][j] = 1;
            else {
                if (str[i] == str[j]) dp[i][j] = dp[i + 1][j - 1] + 2;
                else dp[i][j] = max(dp[i][j - 1], dp[i + 1][j]);
            }
        }
        
    printf("%d", n - dp[0][n - 1]);
    
    return 0;
}