[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自动机)的更多相关文章

  1. luoguP5319 [BJOI2019]奥术神杖(分数规划,AC自动机DP)

    luoguP5319 [BJOI2019]奥术神杖(分数规划,AC自动机DP) Luogu 题解时间 难点在于式子转化,设有c个满足的子串,即求最大的 $ ans = \sqrt[c]{\prod_{ ...

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

    对最终答案取对数,得到$\ln(Ans)=\frac{1}{c}\sum \ln(v_i)$,典型的分数规划问题.二分答案后,对所有咒语串建立AC自动机,然后套路地$f[i][j]$表示走到T的第i个 ...

  3. [BJOI2019]奥术神杖——AC自动机+DP+分数规划+二分答案

    题目链接: [BJOI2019]奥术神杖 答案是$ans=\sqrt[c]{\prod_{i=1}^{c}v_{i}}=(\prod_{i=1}^{c}v_{i})^{\frac{1}{c}}$. 这 ...

  4. [BJOI2019]奥术神杖(分数规划+AC自动机+DP)

    题解:很显然可以对权值取对数,然后把几何平均值转为算术平均值,然后很显然是分数规划.先对每个模式串建立AC自动机,每个节点w[i],sz[i]分别表示以其为前缀的字符串,然后再二分最优解k,然后w[i ...

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

    题目大意: 给出一个长度 $n$ 的字符串 $T$,只由数字和点组成.你可以把每个点替换成一个任意的数字.再给出 $m$ 个数字串 $S_i$,第 $i$ 个权值为 $t_i$. 对于一个替换方案,这 ...

  6. [BJOI2019] 奥术神杖 [取log+AC自动机+dp]

    题面 传送门 思路 首先,看到这个乘起来开根号的形式,应该能想到用取$\log$的方式做一个转化: $\sqrt[n]{\prod_i a_i}=\frac{1}{n}\sum_i \log_b a_ ...

  7. luogu P5319 [BJOI2019]奥术神杖

    传送门 要求的东西带个根号,这玩意叫几何平均数,说到平均数,我们就能想到算术平均数(就是一般意义下的平均数),而这个东西是一堆数之积开根号,所以如果每个数取对数,那么乘法会变成加法,开根号变成除法,所 ...

  8. #loj3089 [BJOI2019]奥术神杖

    卡精度好题 最关键的一步是几何平均数的\(ln\)等于所有数字取\(ln\)后的算术平均值 那么现在就变成了一个很裸的01分数规划问题,一个通用的思路就是二分答案 现在来考虑二分答案的底层怎么写 把所 ...

  9. 【题解】Luogu P5319 [BJOI2019]奥术神杖

    原题传送门 题目让我们最大化\(val=\sqrt[k]{\prod_{i=1}^k w_i}\),其中\(k\)是咒语的个数,\(w_i\)是第\(i\)个咒语的神力 看着根号和累乘不爽,我们两边同 ...

随机推荐

  1. C#连接基于Java开发IM——Openfire

    Openfire简介    Openfire 是开源的.基于可拓展通讯和表示协议(XMPP).采用Java编程语言开发的实时协作服务器.Openfire的效率很高,单台服务器可支持上万并发用户.    ...

  2. Python二级-----------程序冲刺1

    1. 仅使用 Python 基本语法,即不使用任何模块,编写 Python 程序计算下列数学表达式的结果并输出,小数点后保留3位.‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‪‬‪‬‪ ...

  3. layui 轮播图动态数据不显示问题

    layui.use('carousel', function() { var carousel = layui.carousel; var ins = carousel.render({ elem: ...

  4. Linux使用wget、安装Python

    原文:https://blog.csdn.net/ghost_chou/article/details/81905302 1.指定需要安装的目录或创建并访问到该选择的目录下. mkdir /data/ ...

  5. QC API全系列揭秘之Test Execution操作(全网首发)

    (原创文章,转载请注明出处.) 一.QC简介: Quality Center存在至今已经走过了10多个年头,名字从一开始的TD,到后来的QC,再到现在的ALM.所属公司从开始的Mercury到现在的H ...

  6. 微软与开源干货对比篇_PHP和 ASP.NET在 Session实现和管理机制上差异

    微软与开源干货对比篇_PHP和 ASP.NET在 Session实现和管理机制上差异 前言:由于开发人员要靠工具吃饭,可能和开发工具.语言.环境呆的时间比和老婆孩子亲人在一起的时间还多,所以每个人或多 ...

  7. svn + nginx unit + python3自动化发布web服务方法

    本周将python web服务管理更换成nginx unit以后发现接口性能有了明显的提升,访问速度快了不少.不过有个很大的问题就是使用svn自动化发布以后,服务并没有刷新使用新的代码运行,而又不懂得 ...

  8. .net问号的作用

    ??运算符(C# 参考)http://msdn.microsoft.com/zh-cn/library/ms173224.aspx 可以为 null 的类型(C# 编程指南)http://msdn.m ...

  9. 数据库【mysql篇】学习笔记

    Windows服务 -- 启动MySQL    net start mysql-- 创建Windows服务    sc create mysql binPath= mysqld_bin_path(注意 ...

  10. 从零开始制作 Hexo 主题

    原文地址:从零开始制作 Hexo 主题 · Ahonn 写在前面 本文将会从零开始开发一个简单的博客主题.样式主要参考 Hexo theme 中的 Noise 主题. 开始之前你需要了解: 模板引擎  ...