洛谷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的同学们为了庆祝春节,准备排练一场舞会. 题目描述 在越来越讲究合作的时代,人们注意的更多的不是个人物的舞姿,而是集体的排列. 为了配合每年的倒计时,同学们决定排出——“数字舞蹈 ...
随机推荐
- 那些使用VSCode写Python踩过的坑(Anaconda配置)
1. 如何在vscode上配置的配置方法请务必一定要直接参考官方文档Getting Started with Python in VS Code,不要去看什么杂七杂八的blog,要么过时要么不准确要么 ...
- openSUSE 安装LAMP记录
按照 openSUSE SDB:LAMP setup安装好了LAMP.运行的大多数命令都是来自与openSUSE SDB:LAMP setup中. 本页面描述如何安装LAMP,这是 Linux Apa ...
- loj2509 hnoi2018排列
题意:对于a数组,求它的一个合法排列的最大权值.合法排列:对于任意j,k,如果a[p[j]]=p[k],那么k<j. 权值:sigma(a[p[i]]*i).n<=50W. 标程: #in ...
- uoj279 题目交流通道
题目:告诉你每两个点之间的最短路距离.构造每条边边权<=m的无向完全图.求有多少种不同边权的图满足最短路限制?n<=400. 标程: #include<cstdio> #inc ...
- 【Codeforces Round #424 (Div. 2) D】Office Keys
[Link]:http://codeforces.com/contest/831/problem/D [Description] 有n个人,它们都要去一个终点,终点位于p; 但是,在去终点之前,他们都 ...
- input判断输入值是否合法
1.判断input输入的值是否合法有很多办法,我这里使用的是在onchange时进行判断,代码如下:[所有主要浏览器都支持] <input type="text" name= ...
- SQL中的long text
SQL中的long text 问题: 解决方法: SELECT CONVERT(VARCHAR(5000),参考文献) AS 参考文献 FROM tpi20160503 出现原因:
- MyEclipse使用总结——在MyEclipse中新建Maven框架的web项目[转]
前面的文章我们已经在本机安装好了maven,同时在myeclipse中配置好了maven的插件. 链接如下: Maven安装----在Windows上安装Maven myeclipse安装maven插 ...
- Spring MVC(四)--控制器接受pojo参数
以pojo的方式传递参数适用于参数较多的情况,或者是传递对象的这种情况,比如要创建一个用户,用户有十多个属性,此时就可以通过用户的pojo对象来传参数,需要注意的是前端各字段的名称和pojo对应的属性 ...
- 简单DP (Preparing for Xtreme 12.0) | STL map使用
当水题遇上了map大坑 晚上写一个dp,弄了半天样例一直不过,对着队友的代码一行行看,发现跟自己逻辑完全一样啊... 然后就逐行输出比对,发现预处理出了问题,把map插入新值的地方改了下,果然就好了. ...