CCF 2016-12 04编码(DP+哈夫曼树)

来源:互联网 发布:mac qq怎么发文件夹 编辑:程序博客网 时间:2024/06/04 19:15

题目:给定一段文字,已知单词a1, a2, …,an出现的频率分别t1, t2, …, tn。可以用01串给这些单词编码,即将每个单词与一个01串对应,使得任何一个单词的编码(对应的01串)不是另一个单词编码的前缀,这种编码称为前缀码。
  使用前缀码编码一段文字是指将这段文字中的每个单词依次对应到其编码。一段文字经过前缀编码后的长度为:
  L=a1的编码长度×t1+a2的编码长度×t2+…+an的编码长度×tn
  定义一个前缀编码为字典序编码,指对于1 ≤ i < nai的编码(对应的01串)的字典序在ai+1编码之前,即a1,a2, …, an的编码是按字典序升序排列的。
  例如,文字E A E C D E B C C E C B D B E中, 5个单词A、B、C、D、E出现的频率分别为1, 3, 4, 2, 5,则一种可行的编码方案是A:000, B:001, C:01, D:10, E:11,对应的编码后的01串为1100011011011001010111010011000111,对应的长度L为3×1+3×3+2×4+2×2+2×5=34。
  在这个例子中,如果使用哈夫曼(Huffman)编码,对应的编码方案是A:000, B:01, C:10, D:001, E:11,虽然最终文字编码后的总长度只有33,但是这个编码不满足字典序编码的性质,比如C的编码的字典序不在D的编码之前。
  在这个例子中,有些人可能会想的另一个字典序编码是A:000, B:001, C:010, D:011, E:1,编码后的文字长度为35。
  请找出一个字典序编码,使得文字经过编码后的长度L最小。在输出时,你只需要输出最小的长度L,而不需要输出具体的方案。在上面的例子中,最小的长度L为34。



思路:这道题首先你要懂得哈夫曼树的原理,即编码原理,然后找到区别,哈夫曼树是每次找最小的两个,和的价值为新的价值,然后再找到最小的两个价值,组成新的价值,其实就是贪心的依次取最小两个数;但是这里因为要满足字母序,所以只能和相邻的值合并,联想到DP中 的石子合并的问题。

但是普通的石子合并算法复杂度为O(n^3),不能满足这道题的规模,因此要用四边形规则优化。

设m[i,j]表示动态规划的状态量。
m[i,j]有类似如下的状态转移方程:
m[i,j]=min{m[i,k]+m[k,j]}(i≤k≤j)
m[i,j]=min{m[i,k]+m[k,j]}(s[i,j-1]≤k≤s[i+1,j])       定义s(i,j)为函数m(i,j)对应的使得m(i,j)取得最小值的k值。(具体证明见另外一篇博客)
#include<iostream>#include<algorithm>using namespace std;#define maxn 1000+5const int INF = (1 << 30);int dp[maxn][maxn], a[maxn], sum[maxn];int s[maxn][maxn];int main(){int n,i,j,start,mink,end,k;int temp;cin >> n;sum[0] = 0;for (i = 1; i <= n; i++){cin >> a[i];sum[i] = sum[i - 1] + a[i];s[i][i] = i;}for (int len = 1; len < n; len++){for (start = 1; start <= n - len; start++){mink = start;temp = INF;end = start + len;for (k = s[start][end - 1]; k <= s[start + 1][end]; k++)//优化{if (temp > (dp[start][k] + dp[k+1][end] + sum[end] - sum[start-1])){mink = k;//找到k值temp = (dp[start][k] + dp[k+1][end] + sum[end] - sum[start-1]);}}s[start][end] = mink;dp[start][end] = temp;}}cout << dp[1][n];system("pause");return 0;}


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 全面屏面对vo华为手机怎么办屏 雅漾喷雾的喷头坏了怎么办 悦诗风吟水里面有小颗粒怎么办 林肯mkz钥匙锁在车内怎么办 八四消毒液弄到衣服上怎么办 微信朋友圈发过的文章想修改怎么办 白色衣服被洗衣液染色了怎么办 准迁证和迁移证不想迁了怎么办 出了迁移证又想迁到其他地方怎么办 高中的会考如果没g合格怎么办 鞋子里自带的鞋垫坏了怎么办 入厕纸把私处伤了一下怎么办? 夏天做月子用姨妈巾热怎么办 涂了痔疮膏后怕粘到内裤怎么办 眼罩里面的蓝色液体干了怎么办 新买的饮水机有塑料味怎么办 白色衣服被洗衣液染荧光了怎么办 衣服碰到了酒店的毛巾被单怎么办 防晒喷雾弄衣服上有荧光怎么办 剑网3重置版删除后有残留怎么办 在超市买到变质的水果怎么办 微信官方电话一直打不通怎么办 对方欠货款股东换了不还怎么办 闲鱼买的东西确认收货有问题怎么办 不让微信好友看到吃鸡的名字怎么办 金鹰贵宾积分卡过期了怎么办 小宝机器人一直停在联网界面怎么办 手机版的有道云笔记忘记邮箱怎么办 钡灌肠复查钡剂排空不良怎么办 两个月宝宝灌肠后不排便怎么办 一岁宝宝肠套叠灌肠后拉肚子怎么办 苹果手机自带的天气没有了怎么办? 衣服在洗衣机里忘记拿出来怎么办 苹果se手机系统占内存太大怎么办 客人把饭店老板打了民警怎么办 商场嫌品牌低端不让入驻怎么办 带着孩子坐飞机座位不在一起怎么办 公司老板跑路了员工该怎么办 超市买的衣服防盗扣忘记取了怎么办 在超市买的衣服那个扣没取怎么办啊 超市散称商品条码老记不住怎么办