1. 程式人生 > >BZOJ P1068 [SCOI2007]壓縮【區間DP】

BZOJ P1068 [SCOI2007]壓縮【區間DP】

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define DB double
#define SG string
#define LL long long
#define Clear(A) memset(A,0,sizeof(A))
#define Fp(A,B,C) for(A=B;A<=C;A++)
#define Fm(A,B,C) for(A=B;A>=C;A--)
using namespace std;
const LL Max=1e2+5;
char CH[Max];
LL N,DP[Max][Max][2];
inline LL Read(){
	LL X=0;char CH=getchar();bool F=0;
	while(CH>'9'||CH<'0'){if(CH=='-')F=1;CH=getchar();}
	while(CH>='0'&&CH<='9'){X=(X<<1)+(X<<3)+CH-'0';CH=getchar();}
	return F?-X:X;
}
inline void Write(LL X){
	if(X<0)X=-X,putchar('-');
	if(X>9)Write(X/10);
	putchar(X%10+48);
}
bool Judge(LL Left,LL Right){
	LL I,J,K,Mid=Left+Right>>1;
	Fp(I,1,Mid-Left+1){
		if(CH[Left+I-1]!=CH[Mid+I]){
			return 0;
		}
	}
	return 1;
}
int main(){
	LL I,J,K;
	scanf("%s",CH+1);N=strlen(CH+1);
	Fm(I,N,1){
		Fp(J,I,N){
			DP[I][J][0]=DP[I][J][1]=J-I+1;
			Fp(K,I,J-1){
				DP[I][J][1]=min(DP[I][J][1],min(DP[I][K][0],DP[I][K][1])+1+min(DP[K+1][J][0],DP[K+1][J][1]));
			}
			Fp(K,I,J-1){
				DP[I][J][0]=min(DP[I][J][0],DP[I][K][0]+J-K);
			}
			if((J-I+1)%2==0&&Judge(I,J)){
				DP[I][J][0]=DP[I][I+J>>1][0]+1;
			}
			if(J==I){
				DP[I][J][1]=N+1;
			}
		}
	}Write(min(DP[1][N][0],DP[1][N][1]));
	return 0;
}