[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. javascript小记四则:用JS写一个滚动横条文字,可以根据需要进行修改;

    网页上的一些广告文字,一直会滚动是怎么做到的,今天给大家演示下,非常简单,源码如下(本案例是在.net平台上,但HTML是通用的): <!DOCTYPE html> <html> ...

  2. Python 基于Python结合pykafka实现kafka生产及消费速率&主题分区偏移实时监控

    基于Python结合pykafka实现kafka生产及消费速率&主题分区偏移实时监控   By: 授客 QQ:1033553122   1.测试环境 python 3.4 zookeeper- ...

  3. ext前后台数据传输的标准化

    一.标准化的数据传输是什么 这里所说的标准化主要是指,使用代理提交数据时,格式必须统一化.标准化,而服务器返回的数据格式也必须是标准化的数据. 简言之,使用代理提交数据时,前台--->后台,后台 ...

  4. 【SpringBoot笔记】SpringBoot如何正确关闭应用

    关闭Spring Boot应用程序,我们可以通过OS命令kill -9 进程ID 实现将进程杀死.但是,有没有一种更好的方式,比如通过REST请求实现?Spring Boot Actoator提供了实 ...

  5. LinuxMint(Ubuntu)安装文泉驿家族黑体字

    文泉驿黑体字家族在Ubuntu上很有用,可以解决系统字体发虚的问题. 通过下面的三条命令安装: sudo apt-get install ttf-wqy-microhei #文泉驿-微米黑 sudo ...

  6. windows10 uwp获取设备当前地理位置(经纬度)

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  7. Mysql原理与优化

    原文:https://mp.weixin.qq.com/s__biz=MzI4NTA1MDEwNg==&mid=2650763421&idx=1&sn=2515421f09c1 ...

  8. java 开发工具记录

    jenkins 持续构建项目 lombok  优雅代码插件 sonarqube 代码检测插件

  9. 【技术说明】iOS10来了,AppCan已全面适配!

    IPhone 7出了,你的肾还好吗?别紧张,不买肾7,同样可以体验最新的iOS10! AppCan对引擎.插件.编译系统等都进行了重要升级,让你的APP轻松适配iOS10!具体如何,请往下看! 引擎 ...

  10. 弱网测试-Network Emulator 网络模拟工具使用

    参考链接 https://www.jianshu.com/p/6a3d38aafac1