A Super Hero

DP?

QwQ这题似乎不能直接贪心2333——

阶段

很明显的阶段性,\(n\)关便为\(n\)个阶段,

状态

分好阶段后,容易构造出状态的表达:
\(f[i,j]\)表示Ma5termind在最开始要带\(f[i,j]\)个子弹,才能打到第\(i\)关,并打倒第\(i\)关第\(j\)个敌人。

状态转移

Ma5termind在第\(i\)关获得的敌人的子弹只能使用到第\(i+1\)关。

可见当前状态是由上一个阶段(即\(i-1\))推过来的

于是我们得到这么个状态转移方程:

\[ \begin{cases} f[i,j]=min(f[i-1,k]|1 \leq k \leq n)&\text{当}b[i-1,k]>p[i,j]\\ f[i,j]=min(f[i-1,k]+p[i,j]-b[i-1,k]|1 \leq k \leq n) &\text{当}b[i-1,k] \leq p[i,j] \end{cases} \]

假的End

70分愉快的炸啦2333

优化?贪心?

没错,就是贪心啦
官方题解中用mapvector实现了一个很玄学的贪心,让我们来分析一下把!

因为\(p[i,j]\)是一个常数,于是我们可以把dp方程变为:

\[ \begin{cases} f[i,j]=min(f[i-1,k]|1 \leq k \leq n)&\text{当}b[i-1,k]>p[i,j]\\ f[i,j]=min(f[i-1,k]-b[i-1,k]|1 \leq k \leq n)+p[i,j] &\text{当}b[i-1,k] \leq p[i,j] \end{cases} \]

所以每个状态更新时就变成了最值查找啦,强行qsort就发挥作用啦!

然后我们就可以用接近\(O(m)\)的时间复杂度寻找更新状态啦。

我们使用map1存上一阶段的状态map,map2为当前阶段的map,

先考虑第二种情况
\[f[i,j]=min(f[i-1,k]-b[i-1,k]|1 \leq k \leq n)+p[i,j] \text{当}b[i-1,k] \leq p[i,j]\]
一言不合上代码:

  j:=1;  k:=1; tmp:=maxlongint;
        while j<=m do
         begin
            while (k<=m) and (map1_b[k]<=map2_p[j]) do
            begin
              tmp:=min(tmp,map1_f[k]-map1_b[k]);
              inc(k);
            end;
           f[i,map2_j_num[j]]:=min(f[i,map2_j_num[j]],tmp+map2_p[j]);//别忘记加上常数p
            inc(j);
         end;

这个操作的时间复杂度忽略常数接近\(O(m)\),为什么是对的?

班门弄斧地证明一下2333,我们用类似数学归纳法的方法证明——

对于j

我们先称满足\(map1_b[k] \leq map2_p[j]\)在map1的\([1,k]\)区间为对于当前状态\(f[i,j]\)的最小满足区间

在这个区间里,那么因为是按照\(map1_b\)为关键字升序排序的,所以后面的\(map1_b[k]\)都会大于\(map2_p[j]\)

所以显然,当前检查到\([1,k]\)是对于当前状态\(f[i,j]\)的最小满足区间,那么这区间中最小的\(f[i-1,k]-b[i-1,k]\)(即\(tmp\))对于\(j\)是最优的 (满足条件\(b[i-1,k]<=p[i,j]\)情况下)

对于j+1?

又因为这个map2_p是按照升序,所以\(j+1\)\(p\)是大于当前\(j\)的,

那么如果\(j+1\)时不更新\(k\),也就是说\(tmp\)不会变,这意味着\([1,k]\)也是他的最小满足区间,所以这个区间中最小值\(tmp\)也是对于\(j+1\)最优的 (满足条件\(p[i,j]>b[i-1,k]\)情况下)

如果更新的话,那就和对于j的情况是类似的啦,我们会继续找到最小满足区间然后更新。

类似的,对于第一种情况,我们也能按照类似这样的方法证明和更新状态,时间复杂度约为\(O(n\times m\times log_2^m)\),空间复杂度约为\(O(n \times m)\)

转载于:https://www.cnblogs.com/bobble/p/7413805.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值