原题传送门 题目让我们最大化\(val=\sqrt[k]{\prod_{i=1}^k w_i}\),其中\(k\)是咒语的个数,\(w_i\)是第\(i\)个咒语的神力 看着根号和累乘不爽,我们两边同取\(\ln\) \[\ln val=\frac{1}{k}\sum_{i=1}^k \ln w_i\] 易知当\(\ln val\)最大化时,\(val\)也最大化.所以我们将问题转化成了最大化\(\frac{1}{k}\sum_{i=1}^k \ln w_i\),我们发现这是算数平均数.我们珂以…
传送门 要求的东西带个根号,这玩意叫几何平均数,说到平均数,我们就能想到算术平均数(就是一般意义下的平均数),而这个东西是一堆数之积开根号,所以如果每个数取对数,那么乘法会变成加法,开根号变成除法,所以我们只要最大化\(\frac{\sum_i ln_{a_i}}{c}\)就行了 这是一个分数规划的形式,首先二分最终答案\(mid\),然后我们要求最大答案,所以要检查\(\frac{\sum_i ln_{a_i}}{c}\)是否可以\(\ge mid\),可以改成\[\sum_i ln_{a_i…
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…
[BJOI2019]奥术神杖(分数规划,动态规划,AC自动机) 题面 洛谷 题解 首先乘法取\(log\)变加法,开\(c\)次根变成除\(c\). 于是问题等价于最大化\(\displaystyle \frac{\sum val_i}{c}\).典型的分数规划的形式. 二分权值\(k\),每个点的点权变成\(val_i-k\),转为求最值,那么直接在\(AC\)自动机上\(dp\)就行了. 注意精度问题. #include<iostream> #include<cstdio> #…
题目链接: [BJOI2019]奥术神杖 答案是$ans=\sqrt[c]{\prod_{i=1}^{c}v_{i}}=(\prod_{i=1}^{c}v_{i})^{\frac{1}{c}}$. 这样不大好求,我们将这个式子取$ln$,变成$ln\ ans=\frac{1}{c}\sum_{i=1}^{c}ln\ v_{i}$. 这显然是一个分数规划,每次二分一个答案$mid$,将每个串的权值都减去$mid$,那么只需要求最大价值是否大于$0$即可. 剩下的问题就是一个在$AC$自动机上的$D…
题目传送门 题目大意 给出一个残缺的字符串,每个位置都 \(\in[0,9]\).有 \(m\) 中贡献,即 \(s,k\),表示该字符串中没出现一次 \(s\),贡献便乘上 \(k\).最后对贡献求 \(c\) 次根,其中 \(c\) 是总出现次数.求贡献的最大值. 字符串长度以及贡献字符串长度之和 \(\le 1500\) 思路 首先你需要想到我们可以全部取 \(\ln\),然后每次贡献就是 \(+k\),求根就是 \(/c\),于是问题就是最大化: \[\frac{\sum k}{c} \…
https://www.luogu.org/problemnew/show/P5319 题解 首先观察我们要求的答案的形式: \[ \biggl(\prod V_i \biggr)^x\ \ \ x=\frac{1}{c} \] 这个东西貌似还不能最优化,根据套路论,把这个东西整体取个\(ln\),于是就变成了: \[ ln\biggl(\biggl(\prod V_i \biggr)^x\biggr)=\frac{1}{x}\sum ln(V_i) \] 然后这个东西就可以分数规划了,验证的话…
题解:很显然可以对权值取对数,然后把几何平均值转为算术平均值,然后很显然是分数规划.先对每个模式串建立AC自动机,每个节点w[i],sz[i]分别表示以其为前缀的字符串,然后再二分最优解k,然后w[i]-=k*sz[i],然后枚举T,在AC自动机上DP一遍,求最大值是否大于0即可. #include<bits/stdc++.h> using namespace std; ; ],fail[N],sz[N],g[N][N],h[N][N]; double w[N],f[N][N]; char T…
卡精度好题 最关键的一步是几何平均数的\(ln\)等于所有数字取\(ln\)后的算术平均值 那么现在就变成了一个很裸的01分数规划问题,一个通用的思路就是二分答案 现在来考虑二分答案的底层怎么写 把所有串拉出来造ac自动机,那么ac自动机上一个点的权值就是 fail树上这个点到祖先的树链上的字符串的权值之和 那么接下来设\(f(i,j)\)表示决策到了第\(i\)个字符,走到自动机节点\(j\)的最大收益大力dp即可 由于我们不希望均值是0,因此额外记录下有没有匹配上模式串即可 二分完了之后把m…
题目大意: 给出一个长度 $n$ 的字符串 $T$,只由数字和点组成.你可以把每个点替换成一个任意的数字.再给出 $m$ 个数字串 $S_i$,第 $i$ 个权值为 $t_i$. 对于一个替换方案,这样定义它的价值: 如果数字串 $S_i$ 在 $T$ 中出现了,那么将 $t_i$ 加入多重集.如果出现多次也要加多次. 它的价值就是这个多重集元素的几何平均数(所有 $c$ 个数的乘积开 $c$ 次方根). 请构造出一个替换方案,使得这个值最大.不用输出这个价值. $1\le n\le 1500,…
题面 传送门 思路 首先,看到这个乘起来开根号的形式,应该能想到用取$\log$的方式做一个转化: $\sqrt[n]{\prod_i a_i}=\frac{1}{n}\sum_i \log_b a_i$ 这里我们把$b$取到$e$,就是$\ln a_i$了,不过实际上$b$取什么都没有问题 那么,这个问题就转化为了求所有匹配的宝石序列的最大平均值 遇到这种多模式串.单模板串的情况,应当第一时间想到AC自动机 我们建立模式串的AC自动机,并在上面跑dp即可完成题目的求解 建立AC自动机的时候,注…
对最终答案取对数,得到$\ln(Ans)=\frac{1}{c}\sum \ln(v_i)$,典型的分数规划问题.二分答案后,对所有咒语串建立AC自动机,然后套路地$f[i][j]$表示走到T的第i个字符,当前在自动机的第j个位置,能得到的最大收益.注意二分的r初始不能设太大,25就可以了,二分终止的eps最好设到1e-5,否则会WA或者TLE. #include<cmath> #include<cstdio> #include<cstring> #include<…
Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的神器,试图借助神器的神秘 力量帮助她们战胜地灾军团. 在付出了惨痛的代价后,精灵们从步步凶险的远古战场取回了一件保存尚完好的神杖.但在经历过那场所有史书都视为禁忌的"诸神黄昏之战"后,神杖上镶嵌的奥术宝石 已经残缺,神力也几乎消耗殆尽.精灵高层在至高会议中决定以举国之力收集残存至今的奥术宝…
LOJ#3089. 「BJOI2019」奥术神杖 看见乘积就取log,开根号就是除法,很容易发现这就是一道01分数规划.. 然后建出AC自动机直接dp就行,判断条件要设成>0,因为起点的值是1,取完ln后是0 #include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define…
[题解] Luogu P5446 [THUPC2018]绿绿和串串 ·题目大意 定义一个翻转操作\(f(S_n)\),表示对于一个字符串\(S_n\), 有\(f(S)= \{S_1,S_2,...,S_{n-1},S_n,S_{n-1},...S_2,S_1 \}\). 现在给定一个长度为\(n\)的字符串\(S^{'}\)表示原字符串\(S\)经过若干次(可能为0)旋转之后的一个前缀, 求原来字符串可能的长度\(l\). 显然当\(l > n\)时一定可行,所以只需要输出所有的\(l\leq…
题目传送门:LOJ #3089. 题意简述: 有一个长度为 \(n\) 的母串,其中某些位置已固定,另一些位置可以任意填. 同时给定 \(m\) 个小串,第 \(i\) 个为 \(S_i\),所有位置都已固定,它的价值为 \(V_i\). 每次每个小串在母串中出现一次,便会给答案的多重集贡献一个 \(V_i\). 最终的答案为多重集的几何平均数,定义空集的几何平均数为 \(1\). 请你求出一个合法母串(往可以填的位置填合法字符)使得答案最大. \(1\le n,s\le 1501\),\(1\…
题目:https://loj.ac/problem/3089 没想到把根号之类的求对数变成算数平均值.写了个只能得15分的暴力. #include<cstdio> #include<cstring> #include<algorithm> #define db double using namespace std; ,K=; ; ,c[N][K],fl[N]; db ans; ],nxt[N<<],vl[N],sm[N]; int l[N],v[N],dy[…
原题传送门 易知这个数列的顺序是不用考虑的 我们看两个数列 \(1,2,3\)和\(3,3,3\)都能删完,再看两个数列\(1,2,3,4\)和\(2,2,4,4\),也都能删完 不难发现,我们珂以把这些数字塞进桶中,记\(cnt_i\)表示数字\(i\)出现的次数,对于每个\(i\),在一颗线段树上把区间\([i-cnt_i+1,i]\)赋值成1(因为一次删\(cnt_i\)个珂以转化成每次删\(1\)个,值从大向小递减),最后看[1,n]上有几个点不是1,这就是题目所求的答案 单点修改就直接…
题意:给你若干个串和一个填了一部分的串.补完这个串使得 (每个串的匹配次数 * 权值) ^ (1 / 所有串匹配次数) 最大. 解:把这个东西随便取一个对数,就变成了分数规划. 二分.然后在AC自动机上DP判定. #include <bits/stdc++.h> ; ; ], tot(), cnt[N], g[N][N], gt[N][N], tans, fail[N], n; double ed[N], f[N][N]; char str[N], ss[N]; inline void get…
关于这道题, 我们可以发现移动顺序不会改变答案, 具体来说, 我们有以下引理成立: 对于一个移动过程中的任意一个移动, 若其到达的位置上有一个棋子, 则该方案要么不能将所有棋子移动到最终位置, 要么可以通过改变顺序使这一次移动合法 证明: 考虑到达位置上的那个棋子, 如果它没有到达最终位置, 则我们考虑将该棋子移至下一步, 如果下一步还有没有到达最终位置的棋子, 则也移动它 否则直接调换这两个棋子的移动顺序即可 好的我们去除了题目中的要求: 「移动过程中不能出现多颗棋子同时在某一格的情况」, 接…
正题 题目链接:https://www.luogu.com.cn/problem/P5319 题目大意 一个长度为\(n\)的串\(T\),用\(0\sim 9\)填充所有的\(.\). 然后给出\(m\)个串和它们的价值. 一个填充方案的价值等于:若\(T\)中出现了\(c\)个给出的串,那价值等于它们的价值乘积开\(c\)次根. \(1\leq m\leq 1501,1\leq V_i\leq 10^9\) 解题思路 \[ans=\sqrt[c]{\prod V_i} \] \[\ln an…
本蒟蒻也来发一次题解第一篇请见谅 这个题有几个要点 1.无向无权图,建图的时候别忘记建来回的有向边[因此WA掉1次 2.无权嘛,那么边长建成1就好了2333333 3.最短路采用迪杰斯特拉(别忘用堆优化)来做,计数操作改装进去,ans[1]=1;迪杰斯特拉更新边长的时候如果大于号(具体见代码)就覆盖,相等的话就加上 4.%楼上SPFA,BFS大佬 具体见代码,其实就是在迪杰斯特拉里面填了几笔(逃 代码巨丑(捂脸) #include<cstdio> #include<cstring>…
题意 你有一个长度为 $n$ 的模板串(由 $0-9$ 这 $10$ 个数字和通配符 $.$ 组成),还有 $m$ 个匹配串(只由 $0-9$ 这 $10$ 个数字组成),每个匹配串有一个魔力值 $v_i$.你要把模板串的每个 $.$ 都换成一个数字,使得模板串的魔力值最大.模板串的魔力值定义为:模板串中每出现一次任意一个匹配串 $s_i$,字符串的魔力就 $\times v_i$.最终魔力值开 $c$ 次方根,$c$ 为模板串中出现的匹配串的总数. $1\le n,m,s\le 1501,\s…
感谢 @cmy962085349 提供的hack数据,已经改对了. 先声明,我好像是题解里写双$fhq$ $treap$里唯一能过的...(最后两个点啊) 思路:首先看题目,$MIN_GAP_SORT$ 明显是求它的前驱与后继(可能有相同的),所以就用平衡树,但是又要求两个相邻的数的差,就可以有再开一个平衡树存放差值 实现:抛开奇奇怪怪的的题面,主要考虑这三个操作: 1.$INSERT$ $i$ $k$: 这个很简单,用链表就行了(数组模拟的),但是要注意,插入的时候,要接着上一个在这插入的,还…
讲讲这题的几种做法: 暴力匹配法 rt,暴力匹配,即把字符串存起来一位一位判相等 时间复杂度$ O(n^2·m) $ 再看看数据范围 \(n\le10^5,m\le10^3\) 当场爆炸.当然有暴力分 代码(20pts): #include <bits/stdc++.h> using namespace std; char c[100001][1001]; bool pd(int x, int y) { int l1 = strlen(c[x]), l2 = strlen(c[y]); if(…
传送门 不如先考虑暴力,能删的序列首先有\(1,2,3...n\),还有就是升序排序后从后往前放数,第\(i\)位要么放\(i\),要么放\(i+1\)位置的数,例如\(1,2,4,4,5,6,9,9,9\) 如果一个数\(i\)出现了若干次,假如是\(num_i\)次,我们发现是可以在\(i,i-1,i-2...i-num_i+1\)上放\(i\)的,这样放完之后,如果有的位置没有用到现有的数放上去,那么就要从没用的数里改一个放过来,问题也就是用一堆数,最多能放多少个位置.考虑从后往前放,然后…
传送门 先考虑\(n=1\)的情况不是输入数据都告诉你了吗 然后考虑\(n=2\),可以光线是在弹来弹去的废话,然后射出去的光线是个等比数列求和的形式,也就是\(x_1\sum_{i=1}^{\infty} d^i=x_1\frac{1}{1-d}\),然后弹回去的光线第一个光线就是\(b_i\),然后后面也是等比数列求和,算一下就好了 \(n>2\),我们做完\(n-1\)后,可以把刚刚算过的玻璃看成一块,因为已经知道会射出去多少以及弹回去多少,然后就变成了\(n=2\),那么递推做即可 我写…
传送门 普及dp 设\(f_{i,j}\)表示前\(i\)个城堡,用\(j\)人的最大价值,转移枚举一个对手,如果这个对手在\(i\)这个城堡人数是第\(k\)小的,那么用\(2a_i+1\)人可以得到\(ik\)的价值 #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<vector>…
传送门 首先我们要知道要求什么.显然每次放方块要放一大段不能从中间分开的部分.设\(m=2\)方案为\(f\),\(m=3\)方案为\(g\),\(m=2\)可以放一个竖的,或者两个横的,所以\(f_i=f_{i-1}+f_{i-2}\);\(m=3\),因为只有\(i\)为偶数有值,所以后面的\(i\)其实是\(2i\),然后可以发现要么放三个横的,要么像下面这样放长度为偶数的块 |--| ------ |--| |----| ---- |----| 可以注意到每种长度都有两种方案(长度为\(…
[APIO2008]免费道路 题目描述 新亚(New Asia)王国有 N 个村庄,由 M 条道路连接.其中一些道路是鹅卵石路,而其它道路是水泥路.保持道路免费运行需要一大笔费用,并且看上去 王国不可能保持所有道路免费.为此亟待制定一个新的道路维护计划. 国王已决定保持尽可能少的道路免费,但是两个不同的村庄之间都应该一条且仅由一条 且仅由一条免费道路的路径连接.同时,虽然水泥路更适合现代交通的需 要,但国王也认为走在鹅卵石路上是一件有趣的事情.所以,国王决定保持刚好 K 条鹅卵石路免费. 举例来…