zoukankan      html  css  js  c++  java
  • Jzoj3443 压缩

    一个文本压缩后由若干个单元组成,每个单元由3部分组成:1.正文(小写字母组成的字符串)2.若干个”*”,表示正文的又重复了几次3.单元的结尾符号”$”,显然,对于同一文本,压缩后的表示方法不唯一,但是为了方便,我们要求你采用压缩后字符串最短的压缩方法,如果有多种压缩方法,只需输出任意一种。n<=2000

    看到数据范围我们发现可以用dp,设f[i][j]表示目前在第i位,最后一个循环串的长度为j的情况下,最短的长度

    那么显然,无论怎么样,有一种转移总是成立的,f[i][j]=min(f[i-j][k]+j+1),这相当于新开了一个循环节

    而另一个转移需要满足一个条件,f[i][j]=min(f[i-j][j]+1),当s(i-j+1,i)=s(i-j*2+1,i-j)时,这相当于在循环节里面加入一个*

    那么综合下来转移就是n^3的,我们加上两个优化

    1.令g[i]为min(f[i][k]),避免每次枚举k

    2.判断字串相等用hash

    这样我们可以将复杂度将为n^2

    接下来说一下如何输出方案

    先记录下s[i][j]表示状态i,j的最后一个循环节j循环次数,和上面两种转移对应,s[i][j]=1或者s[i][j]=s[i][i-j]+1

    我们令d[i]表示答案为g[i]时,最后一个循环节的循环次数,令r[i]为此循环节的长度,那么求解g[i]时,就可以顺便求解d[i]和r[i]

    最后输出即可

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define L long long
    using namespace std;
    int n,m=0; char str[2010],A[2010];
    int f[2010][2010],b[2010],d[2010];
    int h[2010],g[2010],s[2010][2010],r[2010];
    __attribute__((optimize("-O3")))
    inline L gH(int l,int r){ return h[r]-h[l-1]*b[r-l+1]; }
    int main(){
    	freopen("compress.in","r",stdin);
    	freopen("compress.out","w",stdout);
    	scanf("%s",str+1); n=strlen(str+1);
    	for(int i=*b=1;i<=n;++i){
    		b[i]=b[i-1]*27;
    		h[i]=h[i-1]*27+str[i]-'a';
    	}
    	memset(g,127,sizeof g); *g=0;
    	for(int i=1;i<=n;++i)
    		for(int j=1;j<=i;++j){
    			f[i][j]=g[i-j]+j+1; s[i][j]=1;
    			if(f[i][j]<g[i]){ d[i]=1; r[i]=j; g[i]=f[i][j]; }
    			if(i>=(j<<1) && gH(i-j+1,i)==gH(i-j*2+1,i-j))
    				if(f[i][j]>f[i-j][j]+1){
    					s[i][j]=s[i-j][j]+1;
    					f[i][j]=f[i-j][j]+1;
    					if(f[i][j]<g[i])
    						{ d[i]=s[i][j]; r[i]=j; g[i]=f[i][j]; }
    				}
    			g[i]=min(g[i],f[i][j]);
    		}
    	for(;n;){
    		A[m++]='$';
    		for(int i=1;i<d[n];++i) A[m++]='*';
    		for(int i=n;i>n-r[n];A[m++]=str[i--]);
    		n-=r[n]*d[n];
    	}
    	reverse(A,A+m); puts(A);
    }


  • 相关阅读:
    Step by step Dynamics CRM 2013安装
    SQL Server 2012 Managed Service Account
    Step by step SQL Server 2012的安装
    Step by step 活动目录中添加一个子域
    Step by step 如何创建一个新森林
    向活动目录中添加一个子域
    活动目录的信任关系
    RAID 概述
    DNS 正向查找与反向查找
    Microsoft Dynamics CRM 2013 and 2011 Update Rollups and Service Packs
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/7774411.html
Copyright © 2011-2022 走看看