题意:给你若干个串和一个填了一部分的串。补完这个串使得 (每个串的匹配次数 * 权值) ^ (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 奥术神杖的更多相关文章

  1. LOJ 3089: 洛谷 P5319: 「BJOI2019」奥术神杖

    题目传送门:LOJ #3089. 题意简述: 有一个长度为 \(n\) 的母串,其中某些位置已固定,另一些位置可以任意填. 同时给定 \(m\) 个小串,第 \(i\) 个为 \(S_i\),所有位置 ...

  2. [BJOI2019]奥术神杖(分数规划,动态规划,AC自动机)

    [BJOI2019]奥术神杖(分数规划,动态规划,AC自动机) 题面 洛谷 题解 首先乘法取\(log\)变加法,开\(c\)次根变成除\(c\). 于是问题等价于最大化\(\displaystyle ...

  3. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

  4. 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.

    没有上司的舞会  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...

  5. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  6. 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

    题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...

  7. 洛谷P1710 地铁涨价

    P1710 地铁涨价 51通过 339提交 题目提供者洛谷OnlineJudge 标签O2优化云端评测2 难度提高+/省选- 提交  讨论  题解 最新讨论 求教:为什么只有40分 数组大小一定要开够 ...

  8. 洛谷P1371 NOI元丹

    P1371 NOI元丹 71通过 394提交 题目提供者洛谷OnlineJudge 标签云端评测 难度普及/提高- 提交  讨论  题解 最新讨论 我觉得不需要讨论O long long 不够 没有取 ...

  9. 洛谷P1538迎春舞会之数字舞蹈

    题目背景 HNSDFZ的同学们为了庆祝春节,准备排练一场舞会. 题目描述 在越来越讲究合作的时代,人们注意的更多的不是个人物的舞姿,而是集体的排列. 为了配合每年的倒计时,同学们决定排出——“数字舞蹈 ...

随机推荐

  1. springcloud(十六)、feign+hystrix+ribbon+zuul应用案例

    在 基于 " sringcloud(十四).ribbon负载均衡策略应用案例 "所有工程的基础上,进行如下操作进行网关设置 1.创建eureka-client-consumer-z ...

  2. leetcode-买卖股票的最佳时机④*

    题目描述: 方法一: class Solution: def maxProfit(self, k: int, prices: List[int]) -> int: if len(prices) ...

  3. 图论最短路径算法——SPFA

    为了不要让太多人被害,我还是说一下这种算法,它实际上很简单,但被人讲着讲着绕晕了. 主要思想 有人说,SPFA是Bellman-Ford的队列优化.这个算法我也懂了,但是还没试过.我不管是什么算法的优 ...

  4. Mac OS下使用ll等命令

    1. 进入用户bash_profile文件 vi ~/.bash_profile 2. 添加如下命令 alias ll='ls -l' alias la='ls -A' alias l='ls -CF ...

  5. 富文本vue-quill-editor修改图片上传方法

    富文本vue-quill-editor修改图片上传方法 HTML 代码 HTML codes <!-- 上传的组件 --> <upload style="display:n ...

  6. SEO-----网站不被收录的原因

    1.  新站的收录较慢 2. 文章质量不高 文章难以阅读  排版乱 内容是别的网站采集来的  很难被收录 3. 网站被降权中 4. 蜘蛛不访问[网站配置] 检查网站是否屏蔽了蜘蛛的爬取[ robots ...

  7. 深入浅出 Java Concurrency (29): 线程池 part 2 Executor 以及Executors[转]

    Java里面线程池的顶级接口是Executor,但是严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具.真正的线程池接口是ExecutorService. 下面这张图完整描述了线程 ...

  8. Android之selector选择器的使用

    1.selector简介 selector中文的意思选择器,在Android中常常用来作组件的背景,实现组件在不同状态下不同的背景颜色或图片的变换.使用十分方便.主要是用来改变ListView和But ...

  9. 2019牛客暑假多校赛(第二场) F和H(单调栈)

    F-Partition problem https://ac.nowcoder.com/acm/contest/882/F 题意:输入一个数n,代表总共有2n个人,然后每个人对所有人有个贡献值,然后问 ...

  10. 数据库备份还原——mysqlbackup与mysqldump对比测试

    1      环境描述 1.1      硬件环境 服务器类型:华为RH5885 IP: 10.148.128.100 内存: 64G 物理CPU个数:4 CPU核数:8 逻辑CPU个数:64 Int ...