洛谷P5319 奥术神杖
题意:给你若干个串和一个填了一部分的串。补完这个串使得 (每个串的匹配次数 * 权值) ^ (1 / 所有串匹配次数) 最大。
解:把这个东西随便取一个对数,就变成了分数规划。
二分。然后在AC自动机上DP判定。
#include <bits/stdc++.h> const int N = ;
const double INF = 1e10, eps = 1e-; int tr[N][], tot(), cnt[N], g[N][N], gt[N][N], tans, fail[N], n;
double ed[N], f[N][N];
char str[N], ss[N]; inline void getfail() { std::queue<int> Q;
Q.push();
fail[] = ;
while(Q.size()) {
int x = Q.front();
if(x != ) {
ed[x] += ed[fail[x]];
cnt[x] += cnt[fail[x]];
}
Q.pop();
for(int f = ; f < ; f++) {
if(tr[x][f]) {
int y = tr[x][f];
if(x == ) fail[y] = ;
else fail[y] = tr[fail[x]][f];
Q.push(y);
}
else {
if(x == ) tr[x][f] = ;
else tr[x][f] = tr[fail[x]][f];
}
}
}
return;
} inline void insert(double v) {
int len = strlen(ss), p = ;
for(int i = ; i < len; i++) {
int f = ss[i] - '';
if(!tr[p][f]) {
tr[p][f] = ++tot;
}
p = tr[p][f];
}
ed[p] += v;
cnt[p]++;
return;
} inline double check(double D) { /// f[i][j] means len i in node j , max value for(int i = ; i <= n; i++) {
for(int j = ; j <= tot; j++) {
f[i][j] = -INF;
}
} double ans = -INF;
f[][] = ;
for(int i = ; i < n; i++) {
for(int j = ; j <= tot; j++) {
//if(sgn(f[i][j] + INF) == 0) continue;
if(f[i][j] == -INF) continue;
//printf("%lf ", f[i][j]);
if(str[i + ] != '.') {
int ff = str[i + ] - '';
int y = tr[j][ff];
if(f[i + ][y] < f[i][j] + ed[y] - D * cnt[y]) {
f[i + ][y] = f[i][j] + ed[y] - D * cnt[y];
g[i + ][y] = j;
gt[i + ][y] = ff;
}
}
else {
for(int ff = ; ff < ; ff++) {
int y = tr[j][ff];
//f[i + 1][y] = std::max(f[i + 1][y], f[i][j] + ed[y] - D * cnt[y]);
if(f[i + ][y] < f[i][j] + ed[y] - D * cnt[y]) {
//printf("ff = %d y = %d \n", ff, y);
f[i + ][y] = f[i][j] + ed[y] - D * cnt[y];
g[i + ][y] = j;
gt[i + ][y] = ff;
}
}
}
}
//puts("");
} for(int j = ; j <= tot; j++) {
if(ans < f[n][j] + eps) {
ans = f[n][j];
tans = j;
}
} return ans;
} int main() { //freopen("my.out", "w", stdout); int m;
double l = , r = ;
scanf("%d%d", &n, &m);
scanf("%s", str + );
double x;
for(int i = ; i <= m; i++) {
scanf("%s%lf", ss, &x);
//printf("i = %d \n", i);
x = log(x);
//printf(" h 21 1 1 \n");
insert(x);
//printf(" fdsgfdsfsdfsh 21 1 1 \n");
r += x;
int len = strlen(ss);
memset(ss, , len * sizeof(char));
}
//printf("gfsiofdsfsdgfs\n"); getfail(); for(int T = ; T <= ; T++) {
double mid = (l + r) / ;
//printf("mid %.10f \n", mid);
double t = check(mid);
//printf("l = %lf r = %lf mid = %lf \n", l, r, mid); if(t > ) {
l = mid;
}
else {
r = mid;
}
} //printf("r = %.10f \n", r);
/// output ways
/*
6 5
2....2
252 62
5225 18
25 7
552 12
2122 18 */ check(l);
for(int i = n; i >= ; i--) {
//printf("ans : %d \n", gt[i][tans]);
//printf("node : j = %d \n", tans);
str[i] = gt[i][tans];
tans = g[i][tans]; } for(int i = ; i <= n; i++) {
putchar(str[i] + '');
}
/*for(int i = 1; i <= n; i++) {
printf("%d \n", str[i]);
}*/ /*puts("");
for(int i = 1; i <= tot; i++) {
printf("i = %d fail = %d | ", i, fail[i]);
for(int j = 0; j < 10; j++) {
printf("%d ", tr[i][j]);
}
puts("");
}*/ return ;
}
AC代码
输出答案前如果不加那一句check(l),会WA第二个点。
洛谷P5319 奥术神杖的更多相关文章
- LOJ 3089: 洛谷 P5319: 「BJOI2019」奥术神杖
题目传送门:LOJ #3089. 题意简述: 有一个长度为 \(n\) 的母串,其中某些位置已固定,另一些位置可以任意填. 同时给定 \(m\) 个小串,第 \(i\) 个为 \(S_i\),所有位置 ...
- [BJOI2019]奥术神杖(分数规划,动态规划,AC自动机)
[BJOI2019]奥术神杖(分数规划,动态规划,AC自动机) 题面 洛谷 题解 首先乘法取\(log\)变加法,开\(c\)次根变成除\(c\). 于是问题等价于最大化\(\displaystyle ...
- 洛谷1640 bzoj1854游戏 匈牙利就是又短又快
bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...
- 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.
没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...
- 洛谷P1108 低价购买[DP | LIS方案数]
题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...
- 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP
题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...
- 洛谷P1710 地铁涨价
P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交 讨论 题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...
- 洛谷P1371 NOI元丹
P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交 讨论 题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...
- 洛谷P1538迎春舞会之数字舞蹈
题目背景 HNSDFZ的同学们为了庆祝春节,准备排练一场舞会. 题目描述 在越来越讲究合作的时代,人们注意的更多的不是个人物的舞姿,而是集体的排列. 为了配合每年的倒计时,同学们决定排出——“数字舞蹈 ...
随机推荐
- LoadRunner例子:检查点为参数的一个例子
LoadRunner例子:检查点为参数的一个例子 检查点是LoadRunner的一个功能,用来验证业务功能的正确性.如果检查的内容是变化的,脚本该如何写呢? 问题提出:LoadRunner订票网站例子 ...
- [JZOJ3171] 【GDOI2013模拟4】重心
题目 描述 题目大意 有一堆长为222的矩形,最下面的右端点横坐标为000. 每个矩形都有其固定的质量. 将这些矩形堆在一起,使得最右边的横坐标最大,并且满足它不会塌掉(满足物理学). 思考历程 首先 ...
- 倍增(在线)求LCA
这几天,提高B组总是有求LCA的题.由于我是蒟蒻,所以老是做不出来,直接上暴力.现在才弄懂. 没耐心看前面部分的大神门可以直接看后面. ST(RMQ)算法(在线)求LCA LCA是什么? 在一棵树上, ...
- tip:删除数组中的undefined
this.checkedImg = this.checkedImg.filter(Boolean)
- 微信小程序 button 按钮所有默认的样式
小程序默认样式 // 默认样式 button { position:relative; display:block; margin-left:auto; margin-right:auto; padd ...
- TmodJs:常用语法
ylbtech-TmodJs:常用语法 1.返回顶部 1.循环 {{each items as item index}} <tr> <td>{{index+1}}</td ...
- Java 使用JDBC连接MySQL
// 这学期本来不打算深入学习Java的,课上的小项目也就随便写了一个简单计算器和扫雷游戏就糊弄过去.可是我们的Eliza老师偏偏什么都讲了,考虑到期末也会涉及到JDBC的内容,前些天试着学习一番. ...
- java基础之Math类
Math类概述Math 类包含用于执行基本数学运算的方法,如初等指数.对数.平方根和三角函数. 成员方法 public static int abs(int a):绝对值 public static ...
- 03-python 学习第三天:文件操作
今天学习了打开文件.读取文件.追加内容的操作. 操作实例1:修改文件 思路: 1.修改文件一般有两种方法,一是将文件读取后加载到内存中修改然后写入磁盘,第二种方法是逐行读取并处理.小的文件用第一种方法 ...
- 最新二进制安装部署kubernetes1.15.6集群---超详细教程
00.组件版本和配置策略 00-01.组件版本 Kubernetes 1.15.6 Docker docker-ce-18.06.1.ce-3.el7 Etcd v3.3.13 Flanneld v0 ...