zoukankan      html  css  js  c++  java
  • 【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
    ",ans);
    }
  • 相关阅读:
    微信红包开发
    第一次开博客,留此纪念
    数据结构--树(遍历,红黑,B树)
    c++之vector
    动态规划求解最长公共子序列问题
    c++之map
    k-折交叉验证(k-fold crossValidation)
    prim算法
    快速排序算法
    浙大机试题目
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11279778.html
Copyright © 2011-2022 走看看