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

Luogu

题解时间

难点在于式子转化,设有c个满足的子串,即求最大的 $ ans = \sqrt[c]{\prod_{ i = 1 }^{ c } w_{i} } $ 。

取个对数变成 $ \ln Ans = \frac{1}{c} \sum_{ i = 1 } ^ { c } \ln w_{i} $ 。

很明显是0/1分数规划。

二分mid倒腾一下式子变成 $ \sum_{ i = 1 }^{ c } ( \ln w_{i} - mid ) > 0 $ 。

然后就随便做了。

#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
struct pat{int x,y;pat(int x=0,int y=0):x(x),y(y){}bool operator<(const pat &p)const{return x==p.x?y<p.y:x<p.x;}};
template<typename TP>inline void read(TP &tar)
{
TP ret=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){ret=ret*10+(ch-'0');ch=getchar();}
tar=ret*f;
}
namespace RKK
{
const int N=1511;
const double eps=1e-6; int n,m;double w[N];
char str[N],rts[N]; int tcnt=0,to[N][10],fail[N],cnt[N];double v[N];
void insert(char *s,int id)
{
int len=strlen(s+1),px=0;
for(int i=1;i<=len;i++)
{
int &t=to[px][s[i]-'0'];
if(!t) t=++tcnt;px=t;
}
cnt[px]++,v[px]+=w[id];
}
queue<int> q;
void getfail()
{
for(int i=0;i<10;i++)if(to[0][i]) q.push(to[0][i]);
while(!q.empty())
{
int px=q.front();q.pop();
for(int i=0;i<10;i++)
{
int &t=to[px][i];
if(!t) t=to[fail[px]][i];
else fail[t]=to[fail[px]][i],cnt[t]+=cnt[fail[t]],v[t]+=v[fail[t]],q.push(t);
}
}
}
double dp[N][N];
int fr[N][N],g[N][N];
int work(double k)
{
for(int i=0;i<=n;i++)for(int j=0;j<=tcnt;j++) dp[i][j]=-1e18;
dp[0][0]=0;for(int i=1;i<=n;i++)for(int j=0;j<=tcnt;j++)if(dp[i-1][j]!=-1e18)
for(int b=0;b<10;b++)if(str[i]=='.'||str[i]-'0'==b)
{
int px=to[j][b];if(dp[i][px]<dp[i-1][j]+v[px]-k*cnt[px])
dp[i][px]=dp[i-1][j]+v[px]-k*cnt[px],fr[i][px]=j,g[i][px]=b;
}
double ret=-1e18;for(int i=0;i<=tcnt;i++) ret=max(ret,dp[n][i]);return ret>0;
} int prt[N];
int main()
{
scanf("%d%d%s",&n,&m,str+1);
for(int i=1;i<=m;i++)
scanf("%s%lf",rts+1,&w[i]),w[i]=log(w[i]),insert(rts,i);
getfail();
double ql=0,qr=21,qm,qa=0;
while(qr-ql>eps)
qm=(ql+qr)/2,work(qm)?qa=qm,ql=qm:qr=qm;
work(qa);
int px=0;for(int i=0;i<=tcnt;i++)if(dp[n][i]>0){px=i;break;}
for(int i=n;i;i--) prt[i]=g[i][px],px=fr[i][px];
for(int i=1;i<=n;i++) printf("%d",prt[i]);putchar('\n');
return 0;
}
}
int main(){return RKK::main();}

luoguP5319 [BJOI2019]奥术神杖(分数规划,AC自动机DP)的更多相关文章

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

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

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

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

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

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

  4. P5319-[BJOI2019]奥术神杖【0/1分数规划,AC自动机,dp】

    正题 题目链接:https://www.luogu.com.cn/problem/P5319 题目大意 一个长度为\(n\)的串\(T\),用\(0\sim 9\)填充所有的\(.\). 然后给出\( ...

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

    [BJOI2019]奥术神杖(分数规划,动态规划,AC自动机) 题面 洛谷 题解 首先乘法取\(log\)变加法,开\(c\)次根变成除\(c\). 于是问题等价于最大化\(\displaystyle ...

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

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

  7. POJ1625 Censored!(AC自动机+DP)

    题目问长度m不包含一些不文明单词的字符串有多少个. 依然是水水的AC自动机+DP..做完后发现居然和POJ2778是一道题,回过头来看都水水的... dp[i][j]表示长度i(在自动机转移i步)且后 ...

  8. HDU2296 Ring(AC自动机+DP)

    题目是给几个带有价值的单词.而一个字符串的价值是 各单词在它里面出现次数*单词价值 的和,问长度不超过n的最大价值的字符串是什么? 依然是入门的AC自动机+DP题..不一样的是这题要输出具体方案,加个 ...

  9. HDU2457 DNA repair(AC自动机+DP)

    题目一串DNA最少需要修改几个基因使其不包含一些致病DNA片段. 这道题应该是AC自动机+DP的入门题了,有POJ2778基础不难写出来. dp[i][j]表示原DNA前i位(在AC自动机上转移i步) ...

随机推荐

  1. Solution -「CF 1372E」Omkar and Last Floor

    \(\mathcal{Description}\)   Link.   给定一个 \(n \times m\) 的矩阵,每行被划分为若干段,你可以钦定每段中恰好一个位置为 \(1\),其余位置为 \( ...

  2. Solution -「POJ 3710」Christmas Game

    \(\mathcal{Decription}\)   Link.   定义一棵圣诞树: 是仙人掌. 不存在两个同一环上的点,度数均 \(\ge 3\).   给出 \(n\) 棵互不相关的圣诞树,双人 ...

  3. Nginx--Sorry, the page you are looking for is currently unavailable

  4. centos7对外开放端口号

    前提:防火墙处于打开状态 1:查看防护墙启动状态:systemctl  status firewalld 2:开启:systemctl start firewalld 3:关闭:systemctl s ...

  5. k8s功能、各组件介绍以及pod创建流程

    一.什么是Kubernetes Kubernetes(k跟s中间隔了8个字母又称k8s) 是谷歌开源的容器集群管理系统,是 Google 多年大规模容器管理技术Borg 的开源版本,主要功能包括: 基 ...

  6. 部署Nginx网站服务

    编译安装Nginx nginx 官方 : http://nginx.org/ yum -y install pcre-devel zlib-devel   ##安装相关依赖包 ./configure ...

  7. 金融行业BI可视化报表,直观体验数据的价值

    现在,数据已成为非常重要的资产.之前,人们只是把它当作一种附属品,由客户来办理业务,在系统中产生了这样的附属品.但如今,发现在客户办理业务这一信息中,蕴藏着一些客户的需求,积聚成千条这种信息,可以洞察 ...

  8. BI驾驶舱是什么?BI管理驾驶舱主要内容及特点

    BI驾驶舱,顾名思义就是商业智能中让企业管理者对企业的管理能够找到在飞机或汽车驾驶舱里面的驾驶感觉.BI管理驾驶舱系统是专为企业管理层设计的BI分析系统,,是为企业高层打造的虚拟办公场景,有利于更好地 ...

  9. [MethodImpl(MethodImplOptions.Synchronized)]与lock机制

    [MethodImpl(MethodImplOptions.Synchronized)]与lock机制 在进行.NET开发时,经常会遇见如何保持线程同步的情况.在众多的线程同步的可选方式中,加锁无疑是 ...

  10. Python常用内建模块和第三方库

    目录 内建模块 1  datetime模块(处理日期和时间的标准库) datetime与timestamp转换 str与datetime转换 datetime时间加减,使用timedelta这个类 转 ...