【Luogu】P3847调整队形(DP)

  题目链接

  DP果真是考思维啊

  增加一个数的操作等价于删掉那个不和谐的数的操作。

  所以1、2操作可以忽略。

  剩下3、4操作,则可以设计f[i][j]是将区间[i,j]变成回文序列需要的操作数。

  if(a[i]==a[j])  f[i][j]=f[i+1][j-1];

  如果不一致的话,考虑改、删左边、删右边三种操作。

  

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<algorithm>
using std::min;
inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')    f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num=num*10+ch-'0';
        ch=getchar();
    }
    return num*f;
}

int f[3300][3300];
int s[3300];

int main(){
    int n=read();
    for(int i=1;i<=n;++i)    s[i]=read();
    for(int len=2;len<=n;++len)
        for(int i=1;i+len-1<=n;++i){
            int j=i+len-1;    f[i][j]=0x7fffffff;
            if(s[i]==s[j])    f[i][j]=f[i+1][j-1];
            else{
                f[i][j]=min(f[i][j],f[i+1][j-1]+1);
                f[i][j]=min(f[i][j],f[i][j-1]+1);
                f[i][j]=min(f[i][j],f[i+1][j]+1);
            }
        }
    printf("%d",f[1][n]);
    return 0;
}

 

posted @ 2017-12-21 17:07  Konoset  阅读(170)  评论(0编辑  收藏  举报