Loading

[XXII Open Cup, Korea GP] Goose Coins

前言

参数一多脑子就睡觉

阿达西捧油, 你滴脑子浆糊一样的时候, 不妨听一下雄鹰一样男人的话

思路

首先分析问题, 发现这个背包看起来比较的恐怖, 于是我赛时弃掉了背包做法, 并且死活找不到 \(c_i \mid c_{i + 1}\) 怎么用

赛后发现其实分析问题做的还行, 找性质就很不对了
首先是这种倍数性质有一种不定进制数的感觉, 后面我就在这个基础上处理

首先抛开恰好 \(k\) 个不谈, 只考虑 \(p\) 的约束
因为可行性 \(\rm{dp}\) 注定不能解决, 我们考虑贪心

不难发现由于不定进制数的性质, 我们可以贪心的把 \(p\) 放到高位, 这样一定能保证最小的硬币数, 并且如果有合法解, 通过这种方法也一定能构造出来
具体解释一下, 任何一种合法解在收起来之后必定是这样的, 逆向来讲就是把可以把这样的放置方法拆分成任意合法解
下面称这种贪心方法构造的序列为「起始序列」, 各位记为 \(s_i\)

然后考虑 \(k\) 的约束, 本质上是找到上面的「起始序列」的一个最优拆分 \(h\), 使得恰好拆成 \(k\) 个, 并且要求 \(\sum h_iw_i\) 取到最值

因为 \(n, k\) 相比于 \(p, w_i\) 小很多, 于是不难发现 \(k\) 的约束可以状态维护, 但是 \(w_i\) 必须和 \(p\) 一样找点性质
什么时候 \(\sum h_iw_i\) 取到最值, 发现并不好直接处理, 但是发现一个关键性质

倘若我们取前 \(r\) 类硬币的时候已经使得 \(\sum h_iw_i\) 取到最值, 那么在这个基础上一定得到后面的最值

于是可以把它丢进 \(\rm{dp}\) 里维护
具体设计状态考虑 \(f_{i, j, l}\) 表示考虑前 \(i\) 类硬币, 已经拆成了 \(j\) 个硬币, \(c_i\) 硬币还有 \(l\) 个的最值 \(\sum h_iw_i\) 可以简单做到 \(\mathcal{O} (n k^2)\)
具体的, 考虑枚举当前到底拆了多少 \(c_i\)\(c_{i - 1}\), 然后简单后缀 \(\min\) 维护即可

更具体的官方题解
  1. 状态定义D[i,j,l]D[i,j,l] 表示处理到第 ii 种硬币时,总硬币数为 jj,且当前剩余 llii-面额硬币的最小重量。
  2. 状态转移:拆分 mmii-面额硬币为 bi=ci/ci1b_i = c_i/c_{i-1}i1i-1-面额硬币:
    D[i1,j+(bi1)m,ai1+bim]=minmlkD[i,j,l]+(biwi1wi)m.D[i-1, j + (b_i - 1)m, a_{i-1} + b_i m] = \min_{m \leq l \leq k} D[i,j,l] + (b_i w_{i-1} - w_i)m.
  3. 复杂度:状态数 O(nk2)O(nk^2),总时间 O(nk2)O(nk^2)

输出结果

• 最小重量为 minlD[1,k,l]\min_l D[1,k,l],若无解则输出 -1
• 最大重量可通过符号翻转后相同算法求得。

总结

  • 考察状态设计
    • 不能用状态维护的问题
      • 固定序列
      • 贪心
        • 拥有贪心性质的状物, 可以丢进 \(\rm{dp}\) 里维护\((\)但是不是状态\()\)
          • 前后不相关的序列取数
    • 能用状态维护的
      • 直接用状态维护并和上面结合
posted @ 2025-03-31 16:42  Yorg  阅读(30)  评论(0)    收藏  举报