0219 成本偏斜编码
* * * *
拉格朗日计划
* * * *
成本偏斜编码

设A和B均为比特串(由0和1组成的序列)。

若从B的左端取和A的长度相等的比特位所得的子串恰好等于A,就称A为B的前缀。

例如,00110是001101001的前缀,但不是00111或100110的前缀。

n元无前缀编码是指由n个不同的比特串组成的集合,这些比特串间两两都不互为前缀。

例如,$\{0000, 0001, 001, 01, 10, 11\}$就是一种六元无前缀编码。

现假定传输比特位0的花费是一分钱,而传输比特位1的花费是四分钱。

那么,上述六元无前缀编码的总花费是35分钱,恰是总花费最低的六元无前缀编码。

记$Cost(n)$总花费最低的n元无前缀编码的费用,例如$Cost(6)=35$。

求$Cost(10^9)$。

本题难度:



解答

基本策略与霍夫曼编码一致。

考虑这样一种二叉树,根节点的值为空串,表示比特串的起始,其它所有节点的值均为0或1,可以规定若当前节点是其父节点的左子节点,则其值为0,否则值为1。

每一条从根节点到每一个叶节点的路径都唯一对应一个比特串,n元无前缀编码就可以按此方式形成一颗有n个叶节点的二叉树,例如题面中的六元无前缀编码对应二叉树:



为叙述方便,以下行文中不区分n元无前缀编码及其所对应的二叉树。

用$T_n=\{a_1,\ldots,a_n\}$表示一个n元无前缀编码,并用$|a_k|$表示编码$a_k$的花费。

记$\|T_n\|_{\ell^{\infty}}$为$T_n$中的编码的最大花费,记$\|T_n\|_{\ell^{1}}$为$T_n$中的编码的总花费。

令$c(i)$为最大花费不超过i的情况下的最多的编码数,即 $$c(i)=\max\{n: \|T_n\|_{\ell^{\infty}}\le i\}.$$ 记$T_{c(i)}^*$为满足上述要求、且总费用最低的树,注意由此定义可知这样的树是唯一的。

对$c(i)$而言,有初值$c(0)=c(1)=c(2)=c(3)=1$,以及递推式 $$c(i)=c(i-1)+c(i-4).$$ 这是因为由最大性可以分别在$T_{c(i-1)}^*$的所有编码前添加一位$0$和$T_{c(i-4)}^*$的所有编码前添加一位$1$,再将两者合并来得到$T_{c(i)}^*$。

再令 $$s(i)=\|T_{c(i)}^*\|_{\ell^1},$$ 则有初值$s(0)=s(1)=s(2)=s(3)=0$(注意一元无前缀编码中总费用最低的是空树),再由$c(i)$的递推构造可得 $$s(i)=s(i-1)+s(i-4)+c(i-1)+4c(i-4).$$ 设m是满足$c(m)\le 10^9$中最大的数,要计算$Cost(10^9)$,还需在$T_{c(m)}^*$中再添加$10^9-c(m)$条编码。

由$T_{c(m)}^*$叶节点数的最大性可知只能扩展那些费用不小于$m-3$的叶节点。

在这样的叶节点下添加两个子节点,相当于在$\|T_{c(m)}^*\|_{\ell^1}$中先移除$m-k$($k=0,1,2,3$),再添加$m-k+1$和$m-k+4$,因此总费用增加$m+5-k$。

为使扩展后的总费用最低,应按k的值从大到小开始扩展,实现中经计算可以验证费用为$m-3$的节点数超过$10^9-c(m)$个,因此只需扩展这一种类型的节点即可。

最后结果为 $$s(m)+(10^9-c(m))\cdot(m+2)=64564225042.$$
target=10**9
c=[1,1,1,1]
s=[0,0,0,0]
while c[-1]<=target:
    s.append(s[-1]+s[-4]+c[-1]+4*c[-4])
    c.append(c[-1]+c[-4])

print (target-c[-2])*len(c)+s[-2]