题意:给你若干个串和一个填了一部分的串。补完这个串使得 (每个串的匹配次数 * 权值) ^ (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. 那些使用VSCode写Python踩过的坑(Anaconda配置)

    1. 如何在vscode上配置的配置方法请务必一定要直接参考官方文档Getting Started with Python in VS Code,不要去看什么杂七杂八的blog,要么过时要么不准确要么 ...

  2. openSUSE 安装LAMP记录

    按照 openSUSE SDB:LAMP setup安装好了LAMP.运行的大多数命令都是来自与openSUSE SDB:LAMP setup中. 本页面描述如何安装LAMP,这是 Linux Apa ...

  3. loj2509 hnoi2018排列

    题意:对于a数组,求它的一个合法排列的最大权值.合法排列:对于任意j,k,如果a[p[j]]=p[k],那么k<j. 权值:sigma(a[p[i]]*i).n<=50W. 标程: #in ...

  4. uoj279 题目交流通道

    题目:告诉你每两个点之间的最短路距离.构造每条边边权<=m的无向完全图.求有多少种不同边权的图满足最短路限制?n<=400. 标程: #include<cstdio> #inc ...

  5. 【Codeforces Round #424 (Div. 2) D】Office Keys

    [Link]:http://codeforces.com/contest/831/problem/D [Description] 有n个人,它们都要去一个终点,终点位于p; 但是,在去终点之前,他们都 ...

  6. input判断输入值是否合法

    1.判断input输入的值是否合法有很多办法,我这里使用的是在onchange时进行判断,代码如下:[所有主要浏览器都支持] <input type="text" name= ...

  7. SQL中的long text

    SQL中的long text 问题: 解决方法: SELECT CONVERT(VARCHAR(5000),参考文献) AS 参考文献 FROM tpi20160503 出现原因:

  8. MyEclipse使用总结——在MyEclipse中新建Maven框架的web项目[转]

    前面的文章我们已经在本机安装好了maven,同时在myeclipse中配置好了maven的插件. 链接如下: Maven安装----在Windows上安装Maven myeclipse安装maven插 ...

  9. Spring MVC(四)--控制器接受pojo参数

    以pojo的方式传递参数适用于参数较多的情况,或者是传递对象的这种情况,比如要创建一个用户,用户有十多个属性,此时就可以通过用户的pojo对象来传参数,需要注意的是前端各字段的名称和pojo对应的属性 ...

  10. 简单DP (Preparing for Xtreme 12.0) | STL map使用

    当水题遇上了map大坑 晚上写一个dp,弄了半天样例一直不过,对着队友的代码一行行看,发现跟自己逻辑完全一样啊... 然后就逐行输出比对,发现预处理出了问题,把map插入新值的地方改了下,果然就好了. ...