失去了以前用STL乱搞的能力……

题目描述

语言也是数学上经常研究的一种数据。

给出数学上关于语言的如下定义:

  • 字母表:大小为 K 的字母表是一个由 K 不同的字符组成的集合。
  • 单词:长度为 m 的单词是以 m 个字母表中的字符组成的字符串。
  • 语言:语言是由若干个单词组成的集合。
  • 非前缀的:一种语言是非前缀的,当且仅当其中任意两个单词不存在前缀关系。

现在每个字母表中的字母有一个权值,单词的权值是单词中每个字母的权值和,语言的权值是单词的权值之和。

例如:

K=2,字母a权值为 2,字母b权值为 5,字符串aba权值为 9。

语言 {ab,aba,b} 不是非前缀的,而非前缀的语言 {aa,ab,b} 权值是 16。

给出n,K,每个字母的权值 Wi,求包含 n 个单词的非前缀语言中最小的权值是多少。

数据范围

对于 20% 的数据,n,K≤5

对于另 30% 的数据,wi=1

对于另 30% 的数据,K=2

对于所有数据,2≤n≤10000,2≤K≤26,1≤wi≤10000

时间限制 1s

空间限制 256 MB


题目分析

整个单词树可以看做trie的样子,

那么我的第一思路就是在这个tire上面树形dp……

既然要dp那么肯定要涉及到开数组空间的问题。

注意到若一层能够“铺满”所有n个节点,那么往下编码是一定不更优的。所以最大情况是补成一个满二叉树。

但是这个数据范围对于树上背包来说不对啊……

于是就活生生卡住一个小时。

回过头来看这个问题:非前缀;最小编码和……

这是个类哈夫曼树的问题啊。

与常规的哈夫曼问题不同,此题既然确定个数而加权不同,就可以从树根往下处理。

于是乎,这么一个贪心扩展的过程,就可以用multiset来维护……

最后STL的细节问题需要注意一下。

 #include<bits/stdc++.h>
typedef long long ll;
const int maxn = ; ll sum,ans;
int n,k,w[maxn];
std::multiset<ll> s; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch = getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch = getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
int main()
{
n = read(), k = read(), ans = 1ll<<;
for (int i=; i<=k; i++)
w[i] = read(), sum += w[i], s.insert(w[i]);
for (ll cnt=sum; cnt<ans;)
{
if (s.size()==n){
if (cnt < ans) ans = cnt;
else break;
}
std::multiset<ll>::iterator p = s.begin();
cnt += sum+(*p)*k;
for (int i=; i<=k; i++)
s.insert(w[i]+*p);
cnt -= *p, s.erase(p);
37 while (s.size() > n)
38 cnt -= *s.rbegin(), s.erase(--s.end());
}
printf("%lld\n",ans);
return ;
}

END

【贪心 哈夫曼树】bzoj2923: [Poi1998]The lightest language的更多相关文章

  1. 贪心(哈夫曼树):HDU 5884 sort

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA2QAAAKACAIAAAB8KCy/AAAgAElEQVR4nOy9a5Adx3UmWL+kHxuekU ...

  2. CF 463A && 463B 贪心 && 463C 霍夫曼树 && 463D 树形dp && 463E 线段树

    http://codeforces.com/contest/462 A:Appleman and Easy Task 要求是否全部的字符都挨着偶数个'o' #include <cstdio> ...

  3. 九度OJ 1172:哈夫曼树 (贪心)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:6701 解决:2954 题目描述: 哈夫曼树,第一行输入一个数n,表示叶结点的个数.需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结 ...

  4. bzoj 4198: [Noi2015]荷马史诗【哈夫曼树+贪心】

    和合并果子类似(但是是第一次听说哈夫曼树这种东西) 做法也类似,就是因为不用知道树的形态,所以贪心的把最小的k个点合为一个节点,然后依次向上累加即可,具体做法同合并果子(但是使用优先队列 注意这里可能 ...

  5. [C++]哈夫曼树(最优满二叉树) / 哈夫曼编码(贪心算法)

    一 哈夫曼树 1.1 基本概念 算法思想 贪心算法(以局部最优,谋求全局最优) 适用范围 1 [(约束)可行]:它必须满足问题的约束 2 [局部最优]它是当前步骤中所有可行选择中最佳的局部选择 3 [ ...

  6. 牛客假日团队赛2 C 修围栏 ( 哈夫曼树,贪心)

    链接:https://ac.nowcoder.com/acm/contest/924/C 来源:牛客网 修围栏 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言6 ...

  7. 哈夫曼树---POJ3253

    http://poj.org/problem?id=3253 这就是 最典型的哈夫曼树的题型,我们就根据这道题学习一下哈夫曼树 这是最开始我们把21据下来之后我们据下8,然后再据下5得到34,可以看出 ...

  8. NOIP初赛 之 哈夫曼树

    哈夫曼树 种根据我已刷的初赛题中基本每套的倒数第五或第六个不定项选择题就有一个关于哈夫曼树及其各种应用的题,占:0-1.5分:然而我针对这个类型的题也多次不会做,so,今晚好好研究下哈夫曼树: 概念: ...

  9. 哈夫曼树Huffman

    哈夫曼树处理这样的一种问题: 给出一棵n个叶子的k叉树,每个叶子有一个权值wi,要求最小化∑wi*di di表示,第i个叶子节点到根节点的距离.(一般是边数) 处理方法比较固定. 贪心的思路:我们让权 ...

随机推荐

  1. git小白的学习

    1.1 Git介绍 1.1.1 什么是Git Git是一个开源的分布式版本控制系统,可以有效.高速地处理从很小到非常大的项目版本管理.Git 是 Linus Torvalds 为了帮助管理 Linux ...

  2. 黑马Spring学习 bean

  3. ·ios 圆角

    uiview 直接设置 view.layer.cornerRadius = 5 uiimageview 还需要在设置view.layer.masksToBounds = true .uiview设置这 ...

  4. css各种水平垂直居中

    css各种水平垂直居中,网上查了一下,总结以下几种 line-height垂直居中 缺点,仅限于单行文字 .item{ text-align: center; height: 100px; line- ...

  5. HDU-2586-How far away(LCA Tarjan离线算法)

    链接:https://vjudge.net/problem/HDU-2586 题意: 勇气小镇是一个有着n个房屋的小镇,为什么把它叫做勇气小镇呢,这个故事就要从勇气小镇成立的那天说起了,修建小镇的时候 ...

  6. loj#6169. 相似序列 hash+主席树

    因为他的相似是在排完序下的 那我就在排序的情况下hash啊 这怎么hash啊 主席树啊! 没了 #include <bits/stdc++.h> #define MAXNODE 50000 ...

  7. NET Core 1.1 静态文件、路由、自定义中间件、身份验证简介

    NET Core 1.1 静态文件.路由.自定义中间件.身份验证简介   概述 之前写过一篇关于<ASP.NET Core 1.0 静态文件.路由.自定义中间件.身份验证简介>的文章,主要 ...

  8. High waits on control file sequential read

    High waits on control file sequential read (文档 ID 2277867.1) In case we run into an issue where cont ...

  9. 《java学习三》并发编程 -------线程池原理剖析

    阻塞队列与非阻塞队 阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞.试图从空的阻塞队列中获取元素的线程将会被阻塞,直到 ...

  10. 使用一条sql语句查询多表的总数

    SELECT sum(列名1) 列名1,sum(列名2) 列名2,sum(列名3) 列名3 FROM ( SELECT count(*) 列名1, 列名2, 列名3 FROM 表1 -- WHERE ...