Educational Codeforces Round 25 F. String Compression(kmp+dp)
阿新 • • 發佈:2017-07-19
targe 次數 技術分享 sprint define turn aps 有一種 枚舉
題目鏈接:Educational Codeforces Round 25 F. String Compression
題意:
給你一個字符串,讓你壓縮,問壓縮後最小的長度是多少。
壓縮的形式為x(...)x(...) x表示(...)這個出現的次數。
題解:
考慮dp[i]表示前i個字符壓縮後的最小長度。
轉移方程解釋看代碼,這裏要用到kmp來找最小的循環節。
當然還有一種找循環節的方式就是預處理lcp,然後通過枚舉循環節的方式。
這裏我用的kmp找的循環節。復雜度嚴格n2。
1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3View Codeusing namespace std; 4 5 void kmp_pre(char *x,int m,int *nxt){ 6 int i,j; 7 j=nxt[0]=-1,i=0; 8 while(i<m){ 9 while(-1!=j&&x[i]!=x[j])j=nxt[j]; 10 nxt[++i]=++j; 11 } 12 } 13 const int N=10000; 14 int len,nxt[N],dp[N],cnt[N]; 15 char s[N],buf[20],str[N]; 16 17int main(){ 18 scanf("%s",s); 19 len=strlen(s); 20 F(i,1,len)cnt[i]=sprintf(buf,"%d",i),dp[i]=i+1; 21 F(i,0,len-1) 22 { 23 strcpy(str,s+i); 24 kmp_pre(str,len-i,nxt); 25 for(int j=1;i+j<=len;j++)//枚舉長度 26 { 27 int L=j-nxt[j];//以j結尾的子串的最小循環節28 if(j%L==0)//如果這個子串的長度恰好能整除最小循環節,那麽可以按照最小循環節壓縮。 29 { 30 dp[i+j]=min(dp[i+j],dp[i]+L+cnt[j/L]); 31 }else dp[i+j]=min(dp[i+j],dp[i]+j+cnt[1]); 32 } 33 } 34 printf("%d\n",dp[len]); 35 return 0; 36 }
Educational Codeforces Round 25 F. String Compression(kmp+dp)