BZOJ1068_压缩_KEY

时间:2021-01-09 14:46:18

题目传送门

区间DP,设f[i][j][0/1]为i~j区间的压缩情况,1表示在插入了一个M。

code:

/**************************************************************
    Problem: 1068
    User: yekehe
    Language: C++
    Result: Accepted
    Time:56 ms
    Memory:1308 kb
****************************************************************/
 
#include <cstdio>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
 
string S;
int f[][][];
 
int check(int i,int j)
{
    int mid=i+j>>;
    for(int k=;k<=mid-i;k++)
        if(S[i+k]!=S[mid++k])return ;
    return ;
}
 
int main()
{
    cin>>S;
    int N=S.size();
        for(int i=N-;i>=;i--)
            for(int j=i;j<N;j++){
                f[i][j][]=f[i][j][]=j-i+;//不进行压缩,初始状态
                for(int k=i;k<j;k++)f[i][j][]=min(f[i][j][],f[i][k][]+j-k);//不加M直接取
                for(int k=i;k<j;k++)
                    f[i][j][]=min(min(f[i][k][],f[i][k][])+min(f[k+][j][],f[k+][j][])+,f[i][j][]);//加了M的情况枚举k在哪里加入M
                if(!((j-i+)&)&&check(i,j)){
                    f[i][j][]=min(f[i][j][],f[i][i+j>>][]+);//这里之所以是0,是因为默认前段为起点,即默认有M存在。(类似于i~j区间为一个单独的串)
                }
                if(!(i^j))f[i][j][]=N+;//i==j
            }
    printf("%d",min(f[][N-][],f[][N-][]));
    return ;
}