[BJOI2019]奥术神杖(分数规划,动态规划,AC自动机)
[BJOI2019]奥术神杖(分数规划,动态规划,AC自动机)
题面
题解
首先乘法取\(log\)变加法,开\(c\)次根变成除\(c\)。
于是问题等价于最大化\(\displaystyle \frac{\sum val_i}{c}\)。典型的分数规划的形式。
二分权值\(k\),每个点的点权变成\(val_i-k\),转为求最值,那么直接在\(AC\)自动机上\(dp\)就行了。
注意精度问题。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
#define MAX 1505
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
struct Node{int son[10],ff,s;double w;}t[MAX];
int tot;
void Insert(char *s,int val)
{
int l=strlen(s+1),u=0;
for(int i=1;i<=l;++i)
{
int c=s[i]-48;
if(!t[u].son[c])t[u].son[c]=++tot;
u=t[u].son[c];
}
t[u].w=log(val);t[u].s+=1;
}
int Q[MAX],L,R;
void BuildFail()
{
L=1;
for(int i=0;i<10;++i)if(t[0].son[i])Q[++R]=t[0].son[i];
while(L<=R)
{
int u=Q[L++];t[u].w+=t[t[u].ff].w;t[u].s+=t[t[u].ff].s;
for(int i=0;i<10;++i)
if(t[u].son[i])t[t[u].son[i]].ff=t[t[u].ff].son[i],Q[++R]=t[u].son[i];
else t[u].son[i]=t[t[u].ff].son[i];
}
}
char T[MAX],S[MAX];int n,m;
double f[MAX][MAX];int g1[MAX][MAX],g2[MAX][MAX];
void Tr(int i,int j,int k)
{
int v=t[j].son[k];
if(f[i][v]<f[i-1][j]+t[v].w)
{
f[i][v]=f[i-1][j]+t[v].w;
g1[i][v]=j;g2[i][v]=k;
}
}
bool check(double K)
{
for(int i=0;i<=tot;++i)t[i].w-=K*t[i].s;
int len=strlen(T+1);
for(int i=0;i<=len;++i)
for(int j=0;j<=tot;++j)f[i][j]=-1e300;
f[0][0]=0;
for(int i=1;i<=len;++i)
for(int j=0;j<=tot;++j)
if(T[i]=='.')for(int k=0;k<10;++k)Tr(i,j,k);
else Tr(i,j,T[i]-48);
double ans=-1e300;
for(int i=1;i<=tot;++i)ans=max(ans,f[len][i]);
for(int i=0;i<=tot;++i)t[i].w+=K*t[i].s;
return ans>0;
}
int main()
{
n=read();m=read();
scanf("%s",T+1);
for(int i=1,v;i<=m;++i)scanf("%s",S+1),v=read(),Insert(S,v);
BuildFail();
double l=0,r=21;
while(r-l>1e-3)
{
double mid=(l+r)/2;
if(check(mid))l=mid;
else r=mid;
}
check(l);int pos=0,len=strlen(T+1);
for(int i=1;i<=tot;++i)if(f[len][i]>f[len][pos])pos=i;
for(int i=len;i;--i)S[i]=g2[i][pos]+48,pos=g1[i][pos];
for(int i=1;i<=len;++i)putchar(S[i]);puts("");
return 0;
}
[BJOI2019]奥术神杖(分数规划,动态规划,AC自动机)的更多相关文章
- luoguP5319 [BJOI2019]奥术神杖(分数规划,AC自动机DP)
luoguP5319 [BJOI2019]奥术神杖(分数规划,AC自动机DP) Luogu 题解时间 难点在于式子转化,设有c个满足的子串,即求最大的 $ ans = \sqrt[c]{\prod_{ ...
- [Luogu5319][BJOI2019]奥术神杖(分数规划+AC自动机)
对最终答案取对数,得到$\ln(Ans)=\frac{1}{c}\sum \ln(v_i)$,典型的分数规划问题.二分答案后,对所有咒语串建立AC自动机,然后套路地$f[i][j]$表示走到T的第i个 ...
- [BJOI2019]奥术神杖——AC自动机+DP+分数规划+二分答案
题目链接: [BJOI2019]奥术神杖 答案是$ans=\sqrt[c]{\prod_{i=1}^{c}v_{i}}=(\prod_{i=1}^{c}v_{i})^{\frac{1}{c}}$. 这 ...
- [BJOI2019]奥术神杖(分数规划+AC自动机+DP)
题解:很显然可以对权值取对数,然后把几何平均值转为算术平均值,然后很显然是分数规划.先对每个模式串建立AC自动机,每个节点w[i],sz[i]分别表示以其为前缀的字符串,然后再二分最优解k,然后w[i ...
- [BJOI2019]奥术神杖(AC自动机,DP,分数规划)
题目大意: 给出一个长度 $n$ 的字符串 $T$,只由数字和点组成.你可以把每个点替换成一个任意的数字.再给出 $m$ 个数字串 $S_i$,第 $i$ 个权值为 $t_i$. 对于一个替换方案,这 ...
- [BJOI2019] 奥术神杖 [取log+AC自动机+dp]
题面 传送门 思路 首先,看到这个乘起来开根号的形式,应该能想到用取$\log$的方式做一个转化: $\sqrt[n]{\prod_i a_i}=\frac{1}{n}\sum_i \log_b a_ ...
- luogu P5319 [BJOI2019]奥术神杖
传送门 要求的东西带个根号,这玩意叫几何平均数,说到平均数,我们就能想到算术平均数(就是一般意义下的平均数),而这个东西是一堆数之积开根号,所以如果每个数取对数,那么乘法会变成加法,开根号变成除法,所 ...
- #loj3089 [BJOI2019]奥术神杖
卡精度好题 最关键的一步是几何平均数的\(ln\)等于所有数字取\(ln\)后的算术平均值 那么现在就变成了一个很裸的01分数规划问题,一个通用的思路就是二分答案 现在来考虑二分答案的底层怎么写 把所 ...
- 【题解】Luogu P5319 [BJOI2019]奥术神杖
原题传送门 题目让我们最大化\(val=\sqrt[k]{\prod_{i=1}^k w_i}\),其中\(k\)是咒语的个数,\(w_i\)是第\(i\)个咒语的神力 看着根号和累乘不爽,我们两边同 ...
随机推荐
- Java开发笔记(八十五)通过字符流读写文件
前面介绍了文件的信息获取.管理操作,以及目录下的文件遍历,那么文件内部数据又是怎样读写的呢?这正是本文所要阐述的内容.File工具固然强大,但它并不能直接读写文件,而要借助于其它工具方能开展读写操作. ...
- QuickBI助你成为分析师——计算字段功能
摘要: 在用户创建报表时,通过现有字段数据不能直接满足展示需求,需要进行一定建模操作.目前产品支持在数据集编辑界面进行初步建模,下面主要介绍新建字段功能,以达到展示需求. 在用户创建报表时,有时通过现 ...
- Openlayers系列(一)关于地图投影相关错误的解决方案
背景 近期开发以MongoDB为基础的分布式地理数据管理平台系统,被要求做一个简单的demo给客户进行演示.于是笔者便打算向数据库中存储一部分瓦片数据,写一个简单的存取服务器,使用Openlayers ...
- MyDAL - like && not like 条件 使用
索引: 目录索引 一.API 列表 C# 代码中 String.Contains("conditionStr") 生成 SQL 对应的 like '%conditionStr%' ...
- [20190419]shared latch spin count 2.txt
[20190419]shared latch spin count 2.txt --//上午测试shared latch XX模式的情况,链接:http://blog.itpub.net/267265 ...
- JavaScript(四)变量
变量的声明 在JavaScript程序中,使用一个变量之前应当使用关键字var进行声明,如下所示:var num;var sum; 也可以写成var num,sum,avg;如果只是声明变量而没有给变 ...
- U盘启动盘安装Windows10操作系统详解
没有装过系统的同学,总以为装系统很神秘?是专业技术人员干的事情.今天我们来看看怎么借助常用的U盘装上全新的win10系统. 准备材料: 软件软碟通,可上官网下载:https://cn.ultraiso ...
- 解决 WordPress“正在执行例行维护,请一分钟后回来”
WordPress在升级程序.主题.插件时,都会先切换到维护模式,也就是显示 “正在执行例行维护,请一分钟后回来(Briefly unavailable for scheduled maintenan ...
- com.netflix.zuul.exception.ZuulException: Hystrix Readed time out
通过API网关路由来访问用户服务,zuul默认路由规则 :http://zuul的Host地址:zuul端口/要调用的服务名/服务方法地址 浏览器中打开http://127.0.0.1:8000/wa ...
- Microsoft Store应用安装路径和应用推荐——如何用Linux命令操控windows
本人是cnblog萌新,刚学编程不久的菜鸟,这是我的第一篇博客,请各位轻喷 Microsoft store安装路径: 相信很多人都跟我一样有强迫症,文件找不到安装目录就不舒服.一开始在系统盘找不到Wi ...