首页 > 其他 > 详细

【SCOI2007】压缩

时间:2019-08-01 01:38:43      阅读:90      评论:0      收藏:0      [点我收藏+]

题面

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);
}

 

【SCOI2007】压缩

原文:https://www.cnblogs.com/shxnb666/p/11279778.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!