[Andrew Stankevich's Contest#21] Lempel-Ziv Compression
Problem Description
Most modern archivers, such as WinRAR or WinZIP, use modifications of Lempel-Ziv method as their primary compression algorithm. Although decompression of LZ-compressed archives is usually easy and fast, the compression process itself is often rather complicated and slow. Therefore professional archivers use approximation methods that sometimes do not allow to achieve the best possible compression.
This situation doesn’t satisfy your chief George. He would like to create the best archiver WinGOR. The archiver will use the following modification of LZ77 algorithm.
The text is partitioned to chunks of length not exceeding 4096. Each chunk is compressed independently. We will describe the decompression of one chunk t. Based on this description, you will have to create a compression algorithm that will create the shortest possible compressed chunk x from the given chunk t.
The compressed chunk is written down as the sequence of plain characters and repetition blocks. Plain character is 8 bits long. When decompressing, plain character c is simply copied to output. Repetition block (r; l) consists of two parts: reference r and length l, each 12 bits long. Reference r is an integer number between 1 and 4095. When repetition block (r; l) is obtained after decompressing i − 1 characters of text, characters t[i − r ... i − r + l − 1] are copied to output. Note, that r can be less than l, in this
case recently copied characters are copied to output as well.
To help decompressor distinguish between plain characters and repetition blocks a leading bit is prepended to each element of the compressed text: 0 means plain character follows, 1 — repetition block follows.
For example, “aaabbaaabababababab” can be compressed as “aaabb(5,4)(2,10)”. The compressed variant has 8 + 8 + 8 + 8 + 8 + 24 + 24 + 7 = 95 bits instead of 152 in the original text (additional 7 bits are used to distinguish between plain characters and repetition blocks).
Given a text chunk, find its compressed representation which needs fewest number of bits to encode
Input
Output
Sample Input
aaabbaaabababababab
Sample Output
95
aaabb(5,4)(2,10)
题意概述
分析
AC代码
2 // Submission Date: 2014-10-02 16:34:32
3 // Time: 8256MS
4 // Memory: 34624KB
5
6 /*=============================================================================================================================*/
7 /*======================================================Code by Asm.Def========================================================*/
8 /*=============================================================================================================================*/
9 #include <cstdio>
10 #include <iostream>
11 #include <algorithm>
12 #include <cmath>
13 #include <cctype>
14 #include <memory.h>
15 #include <cstring>
16 #include <cstdlib>
17 using namespace std;
18 #define maxn ((int)4.1e3)
19 /*===========================================================TYPES=============================================================*/
20 typedef long long LL;
21
22 /*======================================================GLOBAL VARIABLES=======================================================*/
23 char ch[maxn];
24 int len = 0, minbit[maxn], *next[maxn];
25 int l[maxn], r[maxn], str[maxn];
26 /*==========================================================FUNCTIONS==========================================================*/
27 inline void getnext(int l){
28 int i, j, L = len - l;
29 next[l] = new int[L+2];
30 int *Next = next[l];
31 Next[0] = 0;
32 for(i = 1;i < L;++i){
33 j = Next[i-1] - 1;
34 while(ch[l+i] != ch[l+j+1] && j >= 0)
35 j = Next[j] - 1;
36 if(ch[l+i] == ch[l+j+1])
37 Next[i] = j + 2;
38 else Next[i] = 0;
39 }
40 }
41 void printpro(int i){
42 if(str[i] == i){
43 if(r[i])printpro(r[i]-1);
44 int j;
45 for(j = r[i];j <= i;++j)putchar(ch[j]);
46 return;
47 }
48 printpro(str[i]);
49 printf("(%d,%d)", r[i], l[i]);
50 }
51 int main(){
52 #ifdef DEBUG
53 assert(freopen("test","r",stdin));
54 #endif
55 //--------------------------------------------------variables-----------------------------------------------------------
56
57 //-----------------------------------------------------work-------------------------------------------------------------
58 char c;
59 while(isalpha(c = getchar()))str[len] = len, ch[len++] = c;
60 int i, j, Min, t;
61 for(i = 0;i < len - 1; ++i)
62 getnext(i);
63 minbit[0] = 9;
64 for(i = 1;i < len; ++i){
65 Min = 0x7fffffff;
66 for(j = 0;j < i;++j)
67 if(minbit[j] + (i-j)*9 < Min){
68 Min = minbit[j] + (i-j)*9;
69 str[i] = i;
70 r[i] = j+1;
71 }
72 for(j = 0;j < i; ++j){
73 t = next[j][i-j];
74 if(!t)continue;
75 if(minbit[i-t] + 25 < Min){
76 Min = minbit[i-t] + 25;
77 str[i] = i-t;
78 r[i] = i+1-t-j;
79 l[i] = t;
80 }
81 }
82 minbit[i] = Min;
83 }
84 printf("%d\n", minbit[len-1]);
85 printpro(len-1);
86 return 0;
87 }
88 /*=============================================================================================================================*/