[SCOI2007]压缩 区间dp

来源:互联网 发布:数据标准化方法比较 编辑:程序博客网 时间:2024/06/05 05:24
       明显是个区间dp,但是我区间dp就是个渣。。。大哭
       f[i][j]表示区间i到j最短的字符长度;假设前面加了个M,所以初始化f[i][i]=2;当然最开始是不算M的,所以f[1][1]=1;然后就可以区间dp了。
       f[i][j]=min{f[i][j-1]+1};//从上一个加一更新过来(如果不存在重合的话)
if(a[i]==a[j]&&check(i,j))//判断是否有重合部分
f[i][j+j-i-1]=min(f[i][j+j-i-1],f[i][j-1]+1);//重合部分用R代替,所以要+1.注意好下标,最后再用一个dp合并就可以了。
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>using namespace std;#define pos(i,a,b) for(int i=(a);i<=(b);i++)char a[100],b[100];int n;int f[100][100];int check(int i,int j){    pos(k,1,j-i-1)    {       if(a[i+k]!=a[j+k])        return 0;    }    return 1;}int main(){    memset(f,50,sizeof(f));    scanf("%s",&b);    n=strlen(b);    pos(i,1,n)      a[i]=b[i-1];    //cout<<n;         pos(i,1,n)      f[i][i]=2;    f[1][1]=1;    pos(i,1,n)      pos(j,i+1,n)      {         f[i][j]=min(f[i][j-1]+1,f[i][j]);         if(a[i]==a[j]&&check(i,j))           f[i][j+j-i-1]=min(f[i][j+j-i-1],f[i][j-1]+1);      }    pos(i,1,n)      pos(j,i+1,n)        pos(k,i,j-1)          f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]);    cout<<f[1][n];    //while(1);    return 0;}

原创粉丝点击