220426总结
220426总结
第无数次忘开 \(\text{long long}\) 挂分了
顺便还因为数组开小了挂了两道题
数组:只要爆不了就往死里开
类型:只要有可能爆掉就开 \(\text{long long}\)
(我都开到数据范围二倍了怎么也能挂
T1 合并石子
经典的区间dp就不写了(
T2 信使
数据范围 \(1 \leq n \leq 100\),要写最短路,图省事就写的 \(\operatorname{Floyd}\)(真的好省事)
跑完 \(\operatorname{Floyd}\) 后,扫一遍 \(1\) 到 \(i(1\leq i\leq n)\)
如果存在不可到达的点就输出 \(-1\) ,不然寻找最大值
输出最大值
T3 暗黑游戏
二维dp
完全背包转化为了可以取 \(400\) 个的多重背包(\(400\) 有点不必要了,数组开小了也有这方面原因)
多重背包二进制拆成了01背包
存二进制拆分后的物品的数组开小了挂了70...啊啊啊啊啊啊啊啊啊啊
一开始以为是一个物品可以拿 \(\text{Pg}\) 或者 \(\text{Rune}\) 买
测大样例发现,一个物品需要 \(\text{Pg}\) 和 \(\text{Rune}\) 买
设 \(f(i,j)\) 为花费 \(i\) 的 \(\text{Pg}\) 和 \(j\) 的 \(\text{Rune}\) 能获得的最大能力值
状态转移方程:\(f(i,j)=\max(f(i-\text{Pg}_k,j-\text{Rune}_k)+w_k,f(i,j))\)
T4 乘积最大
如果数据范围小一点还行
这 \(40\) 位数据被迫写高精度
写高精度写自闭了
重载了 \(*\) 运算符,重写了 \(\max\) 函数
高精度乘法就是普通的高精度乘法
\(\max\) 函数也是像人类比较数据一样,先比位数,尾数相同从高位向低位比起
设 \(f(i,j)\) 表示用了 \(i\) 个乘号,前 \(j\) 个数可以获得的最大值,\(\text{Num}_{l,r}\) 表示原数中 \(l,r\) 区间组成的数
状态转移方程:\(f(i,j)=\max(f(i,j),f(i-1,k)\times \text{Num}_{k+1,i})\)
状态转移方程的意思是,枚举最后一个乘号加在哪里能获得最大值
初始条件是,添加 \(0\) 个乘号时,最大值为从第一位到当前位组成的数
另外,scanf("%1d",A[i])
可以实现从连续的数字串中每次读一位数字(
T5 最小花费
另外一道因为数组开小了挂掉的题(
显然还是一道最短路
因为数据范围为 \(1\leq n \leq 2000\) ,得写 \(\operatorname{Dijkstra}\) 了
和普通的 \(\operatorname{Dijkstra}\) 不太一样的地方在于,这道题不是加法而是乘法
不过我还是做得有点麻烦,我是算的收取多少的手续费
于是在更新最短路时不得不每次 1 - (1 - a) * (1 - b)
(
但如果直接用扣掉手续费还剩多少的话就会方便很多, a * b
就可以(
最后输出的时候用 \(100\) 除以扣掉手续费剩余的百分数就能得到需要准备多少钱
\(2000\) 个人,最多有 \(1999+1998+\dots+1=\dfrac{(1+1999)\times 1999}{2}=1999000\) 条边(