第无数次忘开 $\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$ 条边(