Loj #3089. 「BJOI2019」奥术神杖

题目描述

Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的神器,试图借助神器的神秘

力量帮助她们战胜地灾军团。

在付出了惨痛的代价后,精灵们从步步凶险的远古战场取回了一件保存尚完好的神杖。但在经历过那场所有史书都视为禁忌的“诸神黄昏之战”后,神杖上镶嵌的奥术宝石

已经残缺,神力也几乎消耗殆尽。精灵高层在至高会议中决定以举国之力收集残存至今的奥术宝石,并重金悬赏天下能工巧匠修复这件神杖。

你作为神术一脉第五百零一位传人,接受了这个艰巨而神圣的使命。 神杖上从左到右镶嵌了 \(n\) 颗奥术宝石,奥术宝石一共有 \(10\) 种,用数字 0123456789

表示。有些位置的宝石已经残缺,用 . 表示,你需要用完好的奥术宝石填补每一处残缺的部分(每种奥术宝石个数不限,且不能够更换未残缺的宝石)。古老的魔法

书上记载了 \(m\) 种咒语 \((S_i,V_i)\),其中 \(S_i\) 是一个非空数字串,\(V_i\) 是这种组合能够激发的神力。

神杖的初始神力值 \(\mathrm{Magic} = 1\),每当神杖中出现了连续一段宝石与 \(S_i\) 相等时,神力值 \(\mathrm{Magic}\) 就会乘以 \(V_i\)。但神杖如果包含

了太多咒语就不再纯净导致神力降低:设 \(c\) 为神杖包含的咒语个数(若咒语类别相同但出现位置不同视为多次),神杖最终的神力值为 \(\sqrt[c]{\mathrm{Magic}}\)。(若 \(c = 0\) 则神杖最终神力值为 \(1\)。)

例如有两种咒语 \((01,3)\) 、\((10,4)\),那么神杖 0101 的神力值为 \(\sqrt[3]{ 3 \times 4 \times 3}\)。

输入格式

第一行两个正整数 \(n,m\),表示宝石数和咒语数。

第二行为一个长度为 \(n\) 的字符串 \(T\),表示初始的神杖。

接下来 \(m\) 行每行一个非空数字串 \(S_i\) 和一个正整数 \(V_i\),表示每种咒语。

输出格式

输出最终神杖上从左到右镶嵌的宝石,多解时任意输出一个即可。

数据范围与提示

\(n,\sum_{i=1}^m|S_i|\leq 150\)。\(V_i\leq 10^9\)

\(\\\)

首先将答案取一个对数,
\[ \displaystyle \log_2^{\sqrt[c]{\prod_{i=1}^c V_i}}=\frac{\sum_{i=1}^c\log_2^{V_i}}{c} \]
要求最大化\(\frac{\sum_{i=1}^c V_i}{c}\)就是裸的\(0/1\)分数规划问题(我竟然没看出来,真是越来越zz了)。具体实现时在\(AC\)自动机上\(DP\)就好了。

代码:

#include<bits/stdc++.h>
#define ll long long
#define N 1505
#define eps 1e-8using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}int n,m;
char s[N],t[N];struct trie {int ch[10];int cnt,fail;double sum;
}tr[N];int cnt=1;
void Insert(char *s,double val) {int len=strlen(s+1);int v=1;for(int i=1;i<=len;i++) {int j=s[i]-'0';if(!tr[v].ch[j]) tr[v].ch[j]=++cnt;v=tr[v].ch[j];}tr[v].cnt++;tr[v].sum+=val;
}void build_fail() {static queue<int>q;for(int i=0;i<10;i++) {if(!tr[1].ch[i]) tr[1].ch[i]=1;else {tr[tr[1].ch[i]].fail=1;q.push(tr[1].ch[i]);}}while(!q.empty()) {int v=q.front();q.pop();tr[v].cnt+=tr[tr[v].fail].cnt;tr[v].sum+=tr[tr[v].fail].sum;for(int i=0;i<10;i++) {if(!tr[v].ch[i]) tr[v].ch[i]=tr[tr[v].fail].ch[i];else {int sn=tr[v].ch[i];tr[sn].fail=tr[tr[v].fail].ch[i];q.push(sn);}}}
}double f[N][N];
double tag[N];
struct node {int x,y,type;node() {}node(int _x,int _y,int _type) {x=_x,y=_y,type=_type;}
};node fr[N][N];
bool chk(double ans) {for(int i=1;i<=cnt;i++) tag[i]=tr[i].sum-tr[i].cnt*ans;for(int i=0;i<=n;i++)for(int j=1;j<=cnt;j++)f[i][j]=-1e9;f[0][1]=0;for(int i=0;i<n;i++) {for(int j=1;j<=cnt;j++) {if(f[i][j]<-1e6) continue ;if(s[i+1]=='.') {for(int k=0;k<10;k++) {int q=tr[j].ch[k];if(f[i][j]+tag[q]>f[i+1][q]) {f[i+1][q]=f[i][j]+tag[q];fr[i+1][q]=node(i,j,k);}}} else {int q=tr[j].ch[s[i+1]-'0'];if(f[i][j]+tag[q]>f[i+1][q]) {f[i+1][q]=f[i][j]+tag[q];fr[i+1][q]=node(i,j,s[i+1]-'0');}}}}for(int i=1;i<=cnt;i++) if(f[n][i]>0) return 1;return 0;
}void out(int x,int y) {if(!x) return ;out(fr[x][y].x,fr[x][y].y);cout<<fr[x][y].type;
}int main() {n=Get(),m=Get();scanf("%s",s+1);for(int i=1;i<=m;i++) {scanf("%s",t+1);double v=Get();Insert(t,log2(v));}build_fail();double l=0,r=100,mid;while(l+eps<r) {mid=(l+r)/2.0;if(chk(mid)) l=mid;else r=mid-eps;}chk(l);for(int i=1;i<=cnt;i++) {if(f[n][i]>0) {out(n,i);break ;}}return 0;
}

转载于:https://www.cnblogs.com/hchhch233/p/10778558.html

Loj #3089. 「BJOI2019」奥术神杖相关推荐

  1. 「BJOI2019」奥术神杖(AC自动机+DP)

    文章目录 title solution code title solution 令Magic=Vi×Vj×Vk...Magic=V_i\times V_j\times V_k...Magic=Vi​× ...

  2. LOJ 3094 「BJOI2019」删数——角标偏移的线段树

    题目:https://loj.ac/problem/3094 弱化版是 AGC017C . 用线段树维护那个题里的序列即可. 对应关系大概是: 真实值的范围是 [ 1-m , n+m ] :考虑设偏移 ...

  3. loj 3090 「BJOI2019」勘破神机 - 数学

    题目传送门 传送门 题目大意 设$F_{n}$表示用$1\times 2$的骨牌填$2\times n$的网格的方案数,设$G_{n}$$表示用$1\times 2$的骨牌填$3\times n$的网 ...

  4. LOJ 3090 「BJOI2019」勘破神机——斯特林数+递推式求通项+扩域

    题目:https://loj.ac/problem/3090 题解:https://www.luogu.org/blog/rqy/solution-p5320 1.用斯特林数把下降幂化为普通的幂次求和 ...

  5. 「BJOI2019」

    #4372. 「BJOI2019」排兵布阵 题目描述: 小 C 正在玩一款排兵布阵的游戏.在游戏中有 $n$ 座城堡,每局对战由两名玩家来争夺这些城堡.每名玩家有 $m$ 名士兵,可以向第 $i$ 座 ...

  6. 【LOJ】#3090. 「BJOI2019」勘破神机

    LOJ#3090. 「BJOI2019」勘破神机 为了这题我去学习了一下BM算法.. 很容易发现这2的地方是\(F_{1} = 1,F_{2} = 2\)的斐波那契数列 3的地方是\(G_{1} = ...

  7. Loj #3111. 「SDOI2019」染色

    Loj #3111. 「SDOI2019」染色 题目描述 给定 \(2 \times n\) 的格点图.其中一些结点有着已知的颜色,其余的结点还没有被染色.一个合法的染色方案不允许相邻结点有相同的染色 ...

  8. Loj #3055. 「HNOI2019」JOJO

    Loj #3055. 「HNOI2019」JOJO JOJO 的奇幻冒险是一部非常火的漫画.漫画中的男主角经常喜欢连续喊很多的「欧拉」或者「木大」. 为了防止字太多挡住漫画内容,现在打算在新的漫画中用 ...

  9. LOJ#2230. 「BJOI2014」大融合

    LOJ#2230. 「BJOI2014」大融合 题目描述 小强要在$N$个孤立的星球上建立起一套通信系统.这套通信系统就是连接$N$个点的一个树.这个树的边是一条一条添加上去的. 在某个时刻,一条边的 ...

最新文章

  1. 阿里云发布三大人工智能产品:推动AI产业落地
  2. gearman mysql udf
  3. 数据库主键设计之思考
  4. 【转】golang-defer坑的本质
  5. 微信小程序入门五: wxml文件引用、模版、生命周期
  6. jmu-Java-07多线程-同步访问 (10分)
  7. 苹果推出网页版Apple Music 浏览器上听音乐 这波操作有点迟?
  8. 【Druid IO】Instantiation of [simple type, class druid.indexing.kafka.supervisor.KafkaSupervisorTunin
  9. 吝啬的国度(dfs)
  10. 缠论k线合并处理python实现_缠论期货:道琼斯工业指数缠论分解体系5F趋势背驰,3买能否构筑成功?...
  11. 声明类对象加括号与声明指针对象加括号的问题
  12. 书籍推荐 《移动Web手册》 奇舞团
  13. 开源中国上几款免费又好用的OA协同办公系统,真心不错!
  14. 2010世界杯赛程表 收藏一下
  15. java switch的意思_switch与java
  16. mysql表出现crash 修复_MySQL表索引损坏致Crash及修复过程实例
  17. 腾讯云DNS 域名服务器(nameservers)修改
  18. abp .net core linux,Abp vNext框架 从空项目开始 使用ASP.NET Core Web Application-笔记
  19. OmniPlan Pro 4:项目流程管理工具
  20. linux 16中文输入法,ubuntu 16.04 下安装并切换搜狗中文输入法

热门文章

  1. typescript中接口和类的区别
  2. Cuda 程序设计中 Grid 和 Block 维度设置的注意事项
  3. 自动驾驶技术的新进展:智能感知与决策的优化与实现
  4. 网友在深圳买房的实例
  5. 牛皮席差异不同的地方!
  6. Java GUI(图形用户界面)概述
  7. Inversion of Control (IOC)控制反转 有什么好处
  8. Sage X3 VMI业务解决方案
  9. 2022年塔式起重机司机考试及塔式起重机司机试题及解析
  10. java setdaemon_java教程--守护线程setDaemon