【SCOI2007】压缩

题面

https://www.luogu.org/problem/P2470

题解

// luogu-judger-enable-o2
#include<cstdio>
#include<iostream>
#include<cstring>
#define ri register int
#define N 55
#define uLL unsigned long long
#define INF 107
using namespace std;
int f[N][N],n;
char s[N];
const uLL p=107;
uLL pp[N];

struct hash{
  uLL sum[N];
  void init() {
    sum[0]=0;
    for (ri i=1;i<=n;i++) sum[i]=sum[i-1]*p+s[i]-'a';
  }
  uLL getval(int l,int r){
    return sum[r]-sum[l-1]*pp[r-l+1];
  }
} H;

int dfs(int x,int y){
  if (x==0 && y==0) return 0;
  if (f[x][y]!=INF) return f[x][y];

  int &ret=f[x][y];
  if (x==y) {
    for (ri i=0;i<y;i++) if (dfs(x,i)+1<ret) ret=dfs(x,i)+1;
    return ret;
  }

  if (x-1>=y) ret=min(ret,dfs(x-1,y)+1);
  else for (ri i=0;i<y;i++) if (dfs(x,i)+1<ret) ret=dfs(x,i)+1;
  
  int nn=1;
  for (ri i=x-1;i>y;i--) {
    while (i+((1<<nn)-1)*(i-y)<x) nn++;
    if (i+((1<<nn)-1)*(i-y)==x) {
      bool can=1;
      int curr=x;
      while (curr!=i) {
        curr-=(i-y);
        if (H.getval(curr-(i-y)+1,curr)!=H.getval(x-(i-y)+1,x)) can=0;
      }
      if (can) ret=min(dfs(i,y)+nn,ret);
    }
  }
  return ret;
}

int main(){
  pp[0]=1;
  for (ri i=1;i<N;i++) pp[i]=pp[i-1]*p;
  scanf("%s",s+1);
  n=strlen(s+1);
  H.init();
  for (ri i=0;i<N;i++)
    for (ri j=0;j<N;j++) f[i][j]=INF;
  int ans=INF;
  for (ri i=0;i<=n;i++) if (dfs(n,i)<ans) ans=dfs(n,i);
  printf("%d\n",ans);
}

猜你喜欢

转载自www.cnblogs.com/shxnb666/p/11279778.html