CF DP 题选做
CF DP 题选做
题目来源:CF 上 有“dp”tag 的 题目,且难度在 \(2300-2600\) 之间的题目。
1430F
题意:有一把枪,弹容量 \(k\) 发,可以在一瞬间射出枪里面所有的子弹,每发子弹可以杀死 \(1\) 只怪物。每次换弹需要 \(1\) 秒,且弹夹里面的剩余子弹都会报废。有 \(n\) 波怪物,第 \(i\) 波怪物有 \(a_i\) 只,在 \(l_i\) 时刻出现,要在 \(r_i\) 时刻之前打完,保证对于任意 \([l_i,r_i]\) 均不相交,但可能相邻。求最少子弹消耗量,若无法消灭所有怪物,输出 \(-1\),\(1 \le n \le 2000,1 \le k,a_i,l_i,r_i \le 10^9\)。
解析:有一个很显然的方法,如果怪物来的时间比较宽松,则打完后换弹,所以可以考虑计算因换弹而浪费的最小子弹数量,设 \(f_i\) 表示第 \(i\) 波怪物所浪费的子弹的最小值。
倒着考虑,如果第 \(i\) 个区间和 \(i+1\) 区间相邻,则消耗子弹 \(cnt\) 为 \(a_i+f_{i+1}\),否则为 \(a_i\),此时就可以判断是否能打完这波怪物,即判断 \(k(r_i-l_i+1) \le cnt\)。然后计算 \(f_i\),\(f_i=\max\{0,cnt-k(r_i-l_i)\}\),减去是因为这些子弹大可不必浪费。
计算完 \(f_i\) 后,从 \(1\) 到 \(n\) 遍历一遍并维护目前弹夹里面的子弹数计算答案。
1420E
题意:一行有 \(n\) 个守卫,每个守卫有盾牌或者没盾牌,用一个布尔值 \(a_i\) 表示,有盾牌则 \(a_i=1\),否则 \(a_i=0\)。定理一对守卫 \(i,j(i<j)\) 被保护,当且仅当 \(a_i=a_j=0\) 且存在一个 \(x \in [i+1,j-1]\) 满足 \(a_x=1\)。你需要进行 \(\frac{n(n-1)}{2}\) 次操作,每次操作选择一个有盾牌的守卫,将盾牌交给一个相邻的没有盾牌的守卫,对于每个 \(x \in [0,\frac{n(n-1)}{2}]\),求出经过 \(\le x\) 次操作后最多有多少对守卫被保护。\(1 \le n \le 80,0 \le a_i \le 1\)。
分析:最大化被保护的守卫 \(i,j\),可以转化为最小化没被保护的守卫 \(i,j\),一对守卫没被保护当且仅当中间全是 \(0\),很显然能想到一个 dp 的思路,定义 \(f(a,b,c,d)\) 表示考虑前 \(i\) 个守卫,运用恰好 \(b\) 次操作,前 \(i\) 个守卫中有 \(c\) 个 \(0\),\(d\) 个 \(1\),能满足的最小没被保护的数量,发现时空复杂度均是 \(O(n^5)\),无法接受。
发现第四维的 \(d\) 可以通过 \(a,c\) 推算出唯一的可能值,所以只需记录 \(f(a,b,c)\) 即可,空间复杂度从 \(O(n^5)\) 优化成 \(O(n^4)\),但是转移要枚举下一个 \(1\) 的位置,转移时间复杂度为 \(O(n)\),故时间复杂度为 \(O(n^5)\),理论上不可通过,但有些 \(f(a,b,c)\) 不存在对应情况,且有时转移也跑不满 \(O(n)\),所以卡过去了。

浙公网安备 33010602011771号