google code jam PermRLE(最短哈密顿通路)

38 篇文章 0 订阅
37 篇文章 0 订阅

字符串压缩,转换成求哈密顿通路。

问题

Problem

You've invented a slight modification of the run-length encoding (RLE) compression algorithm, called PermRLE.

To compress a string, this algorithm chooses some permutation of integers between 1 and k, applies this permutation to the first k letters of the given string, then to the next block of k letters, and so on. The length of the string must be divisible by k. After permuting all blocks, the new string is compressed using RLE, which is described later.

To apply the given permutation p to a block of k letters means to place the p[1]-th of these letters in the first position, then p[2]-th of these letters in the second position, and so on. For example, applying the permutation {3,1,4,2} to the block "abcd" yields "cadb". Applying it to the longer string "abcdefghijkl" in blocks yields "cadbgehfkilj".

The permuted string is then compressed using run-length encoding. To simplify, we will consider the compressed size of the string to be the number of groups of consecutive equal letters. For example, the compressed size of "aabcaaaa" is 4; the first of the four groups is a group of two letters "a", then two groups "b" and "c" each containing only one letter, and finally a longer group of letters "a".

Obviously, the compressed size may depend on the chosen permutation. Since the goal of compression algorithms is to minimize the size of the compressed text, it is your job to choose the permutation that yields the smallest possible compressed size, and output that size.

分析

Section A. The Hamiltonian cycle in a small world

A Hamilton cycle in a graph is a cycle that visits each node exactly once. Given a weighted, directed, complete graph on n nodes, there are (n-1)! distinct Hamiltonian cycles. It is well known that the problem of finding the shortest (or longest) Hamilton cycle is NP-hard. It is also known to many contestants that, for n as small as 20, dynamic programming makes a difference of n*2n vs. n!, which is the difference between a second and an eternity.

Let's have a look at the n*2n DP trick, in case you have not seen it before.

Without loss of generality, we may view node 0 as the start point of the cycle, as well as its end point. For any subset A of the node set V and any node x in A, we define

dp[A][x] := The shortest path that starts from x, visits each point in A exactly once and ends up at node 0. (*)

To clarify, 0 does not necessary belong to A, but we do count the length of the edge from the last point to node 0. Thus the problem of finding the shortest Hamilton cycle is just dp[V][0]. (Convince yourself, maybe looking at (*).)

 

We need to compute dp[A][x]. For the easy cases where A = {x}, the answer is just the length of edge x→0. Otherwise, we focus on the first step of the path. If the first step is x→y, with edge length q, then we pay dp[A - x][y] + q. In general, dp[A][x] is

  • length(x→0), if A = {x}.
  • min { dp[A - x][y] + length(x→y) | y in A - x }, if |A|>1.

 

Section B. Wrap everything into a small world

For any string, define the number of switches to be the number of times adjacent characters are different in the string. We want to find a permutation that transforms S to one S' where the number of switches is minimal. Assume the length of S is mk. Then S can be viewed as a string with m blocks of length k.

Now we introduce a visual aid to simplify our writing. Let us draw the string S as m rows, each block on a single row. The key image is to count the number of switches one column at a time.

Let us take a semi-concrete example. Suppose that at one point we have decided that 5 is permuted to the 7th position, and that 2 goes to the 8th position. Then without knowing the rest of the permutation, we can inspect the 5th and 2nd characters in each block. Suppose that in Z of the blocks the 5th and the 2nd characters are different, then we know that in any such permutation, we will have to pay the price of Z.

The one exception is the last element of the permutation. In all cases but one, we simply wrap around to the beginning because the end of each k-block touches the beginning of the next k-block in the string, except for the last character in the string. We can handle both cases if we fix the last element of the permutation by trying all possibilities.

Next, we reduce our problem to the one in Section A. Suppose we fix T as the last element in the permutation. Define a weighted, directed, complete graph G on k vertices {1, 2, ..., k}. The weight on the edge x→y is

  • the number of blocks where the x-th character is different from the y-th character in the same block. (if x ≠ T)
  • the number of blocks (excluding the last one) where the x-th character is different from the y-th character in the next block. (if x = T)

It is easy to check that for any permutation, the number of switches is the same as the length of the corresponding Hamiltonian cycle in G.

 

We have k different choices for T. For each T, finding the shortest Hamilton cycle takes O(2k k) time. The construction of the graph takes O(k2m) = O(k |S|) time for each T; it is also easy to construct in O(k2m) time the graphs for all the T's. The running time of the solution is O(2k k + k |S|).

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值