CF1787H 题解

搞了很久才搞明白,写一篇比较详细的题解造福一下后人(

Sol

首先不妨转化一下,把最大得分转化成最小扣分,于是我们发现如果要做题,就要优先做 ki 大的,因为他分减的最快。也可以选择不做他,得分取到 ai,那么把它放在最后做肯定不劣。

于是我们把这些题按照 ki 排序,记 ci=biai,设 fi,j 表示前 i 道题,有 j 道不取 ai 的扣分最小值,容易得到转移:

fi,0=fi1,0+cifi,j=min{fi1,j+ci,fi1,j1+ki×j}

这是 O(n2) 的 DP,我们尝试发现一些东西来优化它。。

如果你真的写出这个 DP 打表并期望得到一些规律:

for(int i=1;i<=n;i++){
    f[i][0]=f[i-1][0]+p[i].c;
    for(int j=1;j<=i;j++)
        f[i][j]=min(f[i-1][j]+p[i].c,f[i-1][j-1]+p[i].k*j);
}

如果你跑一下最后一组样例并把 fi,j 输出:

 5
 10  15
 29  20  19
 44  35  34  15
 52  43  42  23   8
 56  47  46  27  12   4
 62  53  52  33  18  10   6
 80  68  62  51  36  28  24  18
 81  69  63  52  37  29  25  19   1
105  85  75  71  62  49  43  41  29  21

你会惊喜地发现 fi,j 关于 j 是下凸的。

既然发现了它的凸性,我们不妨差分吧!设 gi,j=fi,jfi,j1,我们用 fi,0+k=1jgi,k 替换 fi,j 即可得到:

fi,0+k=1jgi,k=min{fi1,0+k=1jgi1,k+ci,fi1,0+k=1j1gi1,k+ki×j}

把不变的东西提出来:

fi,0+k=1jgi,k=fi1,0+k=1j1gi1,k+min{gi1,j+ci,ki×j}

我们知道 fi,0=fi1,0+ci,所以:

ci+k=1jgi,k=k=1j1gi1,k+min{gi1,j+ci,ki×j}

为了把单个的 gi,j 拎出来,我们将上式中的 j 替换为 j1

ci+k=1j1gi,k=k=1j2gi1,k+min{gi1,j1+ci,ki×(j1)}

然后将两式相减:

gi,j=gi1,j1+min{gi1,j+ci,ki×j}min{gi1,j1+ci,ki×(j1)}

最后你发现这不还是 O(n2) 的吗。。不过如果你真的把这个 DP 写出来并且打表,然后跑最后一组样例并输出 gi,j

    0
   -22    5
   -22   -9   10
   -22   -9    0   15
   -22   -9    0    4   18
   -22   -9    0    4   11   21
   -22   -9    0    4    9   14   24
   -22  -12   -6    3    7   12   17   27
   -22  -12   -6    3    7   12   17   23   30
   -26  -20  -10   -4    5    9   14   19   25   32

你会发现,每一行的前面一段相对于上一行不变。如果你注意力极其惊人,你会发现每一行的后面一段对于上一行的后面一段的差是个定值!!1

结合一下,我们的转移里面有 min 函数,说明其中有规律可言,min 函数到底取哪个值是有规律的。

打表发现,i 固定,存在一个最小的 pos 满足 gi1,pos+ci>ki×pos,使得对于所有的 j<posgi1,j+ciki×j,其余的 j 都不满足这个。

min{gi1,j1+ci,ki×(j1)} 就相当于 min{gi1,j+ci,ki×j} 往后移一位,所以我们可以分成三段来讨论:

  1. 两个 min 全取前面那一项,对应 j<posgi,j=gi1,j
  2. 第一个 min 取后面一项,第二个取前面一项,在 pos 处插入 gi,j=ki×jci
  3. 两个 min 全取后面那一项,对应 jposgi,j=gi1,j+ki

如果你把这些全部注意到了,那么恭喜你,直接平衡树维护上述过程就可以过掉了。

但是你还不满足,为什么是这样的呢???

这基于一个关键条件:对于任意的 i,j,有 gi,jgi,j1ki

我们考虑归纳证明这个条件,对于 i=2 显然成立就不展开了。

当我们对于一个 gi,将其转移到 gi+1 时,考虑上述转移的过程:

先找到一个最小的 pos 满足 gi,pos>ki+1×posci+1

对于左边不变和右边同时增加的那一部分,我们知道 k 是不增的,所以肯定满足。

对于 pos1pos 之间,有:gi+1,posgi+1,pos1=ki+1×posci+1gi,pos1

我们知道 gi,pos1 不满足 gi,pos1>ki+1×(pos1)ci+1,也就是说 gi,pos1ki+1×(pos1)ci+1

所以有 ki+1×posci+1gi,pos1ki+1×posci+1ki+1×(pos1)ci+1=ki+1。即满足。

对于 pospos+1 之间,有:gi+1,pos+1gi+1,pos=gi,pos+1+ki+1ki+1×pos+ci+1ki+1

优雅结束。

回顾一下本题的历程,我们首先取原 DP 数组的差分,然后注意到差分的差分大于一个数由此得出单调性,或许在场上对于我这种,除了打表没什么其他方法吧!

这就是你和 CF 3300 的差距。 —— 一休哥777

posted @   Linge_Zzzz  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示