0%

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$ 条边(