区间dp

X星球的考古学家发现了一批古代留下来的密码。

这些密码是由A、B、C、D 四种植物的种子串成的序列。

仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串)。

由于年代久远,其中许多种子脱落了,因而可能会失去镜像的特征。

你的任务是:

给定一个现在看到的密码串,计算一下从当初的状态,它要至少脱落多少个种子,才可能会变成现在的样子。

输入格式

共一行,包含一个由大写字母ABCD构成的字符串,表示现在看到的密码串。

输出格式

输出一个整数,表示至少脱落了多少个种子。

数据范围

输入字符串长度不超过1000

输入样例1:

ABCBA

输出样例1:

0

输入样例2:

ABDCDCBABC

输出样例2:

3

这题就是一个区间dp,dp[i]][j]代表的是区间i-j中最长的回文串,最后的答案就是n-dp[1][n]

#include<iostream>
#include<algorithm>
#include<cstring> 
using namespace std;
/*
就是区间删几个字母能成回文串 
*/
const int maxn=3e3+100;
char a[maxn];
int dp[maxn][maxn];
int main(){
    scanf("%s",a+1);
    int n=strlen(a+1);
    for(int len=1;len<=n;len++){
        for(int i=1;i+len-1<=n;i++){
            int j=i+len-1;
            if(i==j){
                dp[i][j]=1;
                continue;
            } 
            if(a[i]==a[j]){
                dp[i][j]=dp[i+1][j-1]+2;
            }
            else{
                dp[i][j]=max(dp[i][j],dp[i][j-1]);
                dp[i][j]=max(dp[i][j],dp[i+1][j]); 
            }
        }
    } 
    cout<<n-dp[1][n]<<endl;
} 
 
原文地址:https://www.cnblogs.com/lipu123/p/14617107.html