EOJ Problem #3261 分词 trie + dp + 小剪枝
http://acm.ecnu.edu.cn/problem/3261/
分词
Time limit per test: 1.0 seconds
Time limit all tests: 1.0 seconds
Memory limit: 256 megabytes
有一句句子因为粘贴的时候出现了一点问题空格全部丢失了。现在给一本字典,每个词都对应这个词出现的频率(每十亿)。根据这个频率,我们可以根据下面的公式算出这个词带来的收益 P(word) :
其中 frequency 就是上面所提到的频率。len
指的是单词的长度。
特别的,对于字典中没有出现过的词,P(word)=0 。
请对句子进行适当的分割,使得分割得到的所有词收益之和最大。同一个词可以重复出现,收益算作多次。
Input
先给出一本词典,词典的第一行是词条数(词条数约为 40 000 ),下面每行分别是单词和对应出现频率,用空格隔开。单词中只会出现英文字母大小写,不会有多余的空格。每个单词只会出现一次。频率是一个正实数。
所有单词长度之和不超过 3⋅105
,最长单词长度不超过 30
。
接下来一行一个整数 T (T≤10)
,表示有 T
个查询。
下面 T 行,每行一个句子,句子长度不超过 5 000
。句子中保证只含有英文字母大小写。注意单词匹配时,不区分大小写。
词典数据来源于 Wikipedia Project Gutenberg(可能需要代理),其中 1-10000 词汇。
查询数据来源于 IELTS Test。
Output
对于每组数据,输出两行。
第一行是一个实数,表示最大能达到的收益。输出和答案相差不超过 10−3
即可认为正确。
第二行输出一连串单词,单词和单词之间用空格隔开。满足:
- 把这些单词依次串联起来可以得到原句子;
- 所有单词的收益值相加得到第一行的实数。
Examples
5
ano 10
ther 30
another 10
an 300
other 20
1
another
112.826670
another
5
ano 10.0
ther 30.0
another 10.0
an 300.0
other 2000.0
1
another
212.837691
an other
Note
样例给出的词典与测试数据有所不同。
Source
2017 华东师范大学网赛
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const int maxn = 4e5 + ;
const int N = ;
char str[maxn];
struct Node {
double val;
struct Node * pNext[N];
} tree[maxn];
int t;
struct Node * create() {
struct Node *p = &tree[t++];
p->val = ;
return p;
}
void toInsert(struct Node **T, char str[], double val, int lenstr) {
struct Node *p = *T;
if (!p) p = *T = create();
for (int i = ; str[i]; ++i) {
int id = str[i] - 'a';
if (!p->pNext[id]) p->pNext[id] = create();
p = p->pNext[id];
}
p->val = max(p->val, val);
}
double ask(struct Node *T, char str[], int be, int en) {
if (en - be + > ) return ;
struct Node *p = T;
if (!p) return ;
for (int i = be; i <= en; ++i) {
int id = str[i] - 'a';
if (!p->pNext[id]) return ;
p = p->pNext[id];
}
return p->val;
}
struct ddpp {
double val;
int pre;
} dp[maxn];
int del[maxn], DFN;
bool isok(char ch) {
return ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z';
} void toChange(char str[], int lenstr) {
for (int i = ; i <= lenstr; ++i) {
if (str[i] >= 'A' && str[i] <= 'Z') {
str[i] += ;
}
}
}
char sub[maxn];
void work() {
int n;
scanf("%d", &n);
struct Node *T = NULL;
for (int i = ; i <= n; ++i) {
scanf("%s", str + );
double val;
scanf("%lf", &val);
int lenstr = strlen(str + );
toChange(str, lenstr);
toInsert(&T, str, lenstr * lenstr * log(val), lenstr);
}
int q;
scanf("%d", &q);
while (q--) {
scanf("%s", str + );
int lenstr = strlen(str + );
strcpy(sub + , str + );
toChange(str, lenstr);
for (int i = ; i <= lenstr; ++i) {
dp[i].val = dp[i].pre = ;
for (int j = ; j <= i; ++j) {
double res = ask(T, str, j, i);
if (dp[i].val < dp[j - ].val + res) {
dp[i].val = dp[j - ].val + res;
dp[i].pre = j - ;
}
}
}
++DFN;
int pre = dp[lenstr].pre;
while (pre > ) {
del[pre] = DFN;
pre = dp[pre].pre;
}
printf("%0.10f\n", dp[lenstr].val);
for (int i = ; i <= lenstr; ++i) {
if (del[i - ] == DFN) {
printf(" ");
}
printf("%c", sub[i]);
}
printf("\n");
}
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
#endif
work();
return ;
}
EOJ Problem #3261 分词 trie + dp + 小剪枝的更多相关文章
- EOJ Problem #3249 状态压缩+循环周期+反向递推
限量供应 Time limit per test: 4.0 seconds Time limit all tests: 4.0 seconds Memory limit: 256 megabytes ...
- UVA 3942 Remember the Word (Trie+DP)题解
思路: 大白里Trie的例题,开篇就是一句很容易推出....orz 这里需要Trie+DP解决. 仔细想想我们可以得到dp[i]=sum(dp[i+len[x]]). 这里需要解释一下:dp是从最后一 ...
- EOJ 3261 分词
字典树,$dp$. 记录$dp[i]$为以$i$为结尾获得的最大价值.枚举结尾一段是哪个单词,更新最大值.可以将字典中单词倒着建一棵字典树. 这题数据有点不严谨. 下面这组数据答案应该是负的. 3 a ...
- UVALive - 3942 Remember the Word[Trie DP]
UVALive - 3942 Remember the Word Neal is very curious about combinatorial problems, and now here com ...
- hdu 4540 威威猫系列故事——打地鼠 dp小水题
威威猫系列故事——打地鼠 Time Limit: 300/100 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total ...
- 四维dp 或者 剪枝 + dfs Codeforces Beta Round #6 (Div. 2 Only) D
http://codeforces.com/contest/6/problem/D 题目大意:有一队人,排成一列,每个人都有生命值,你每次可以攻击2~n位置的一个的人,假设每次攻击的位置为pos,那么 ...
- EOJ Monthly 2018.4 (E.小迷妹在哪儿(贪心&排序&背包)
ultmaster 男神和小迷妹们玩起了捉迷藏的游戏. 小迷妹们都希望自己被 ultmaster 男神发现,因此她们都把自己位置告诉了 ultmaster 男神,因此 ultmaster 男神知道了自 ...
- LightOJ - 1322 - Worst Case Trie(DP)
链接: https://vjudge.net/problem/LightOJ-1322 题意: In Computer Science Trie or prefix tree is a data st ...
- zoj3777 Problem Arrangement(状压dp,思路赞)
The 11th Zhejiang Provincial Collegiate Programming Contest is coming! As a problem setter, Edward i ...
随机推荐
- ActivityMq的使用(小例子)
一.ActivityMq的介绍: 1.什么是消息中间件?与传统的传输通讯有什么区别? 异步,无需等待,消息存放在队列里面. 2.为什么要使用消息中间件? 消息中间件可以解决高并发. 两种通讯方式:01 ...
- 白痴qwerta的胡言乱语(一句话日度感想?
10.2 >我tm吹爆这个Latex插件!!!太漂亮了吧?!!! 10.3 >什么鬼气考试 还有这考试的大家也肽水了吧 >再吹一次这个Latex插件!!! 10.6 >今天在琢 ...
- [转]JavaScript的实例化与继承:请停止使用new关键字
JavaScript中的new关键字可以实现实例化和继承的工作,但个人认为使用new关键字并非是最佳的实践,还可以有更友好一些的实现.本文将介绍使用new关键字有什么问题,然后介绍如何对与new相关联 ...
- 洛谷P3205合唱队——区间DP
题目:https://www.luogu.org/problemnew/show/P3205 枚举点,分类为上一个区间的左端点或右端点,满足条件便+=即可: 注意不要重复(当l=2时). 代码如下: ...
- JavaScript-Tool:three.js
ylbtech-JavaScript-Tool:three.js Three.js 是一款运行在浏览器中的 3D 引擎,你可以用它创建各种三维场景,包括了摄影机.光影.材质等各种对象.你可以在它的主页 ...
- FlexPaper+SwfTools实现的在线文档功能
最近一个项目需要实现一个在线浏览文档的功能.准备使用FlexPaper配合Pdf2Swf实现. 主要需求在于: ➔ 文档页数很多,少则几百页,多则上千页. ➔ 相应的文档大小也在50MB以上. ...
- Java虚拟机学习 - 体系结构 内存模型(转载)
一:Java技术体系模块图 二:JVM内存区域模型 1.方法区 也称"永久代” .“非堆”, 它用于存储虚拟机加载的类信息.常量.静态变量.是各个线程共享的内存区域.默认最小值为16MB, ...
- maven变量说明
Maven内置变量说明: ${basedir} 项目根目录 ${project.build.directory} 构建目录,缺省为target ${project.build.outputDirect ...
- JavaWeb_tomcat设置默认应用
在tomcat的server.xml文件中设置默认应用. 在tomcat文件目录里面的conf/server.xml文件中,在<Engine>...</Engine>中再增加一 ...
- JQuery中查找父元素,子元素,追加元素,插入元素和删除元素 及其他常用方法
Jquery之所以强大,和其在获取对象时使用与css选择器兼容的语法有很大关系.而且它还兼容了CSS3的选择器,而且多出了不少. 所以jQuery的选择器也就变得很多很强大.就最基本的有以下四个: $ ...