HDU

题目大意

(N) 种不同面值的硬币,分别给出每种硬币的面值 (v_i) 和数量 (c_i)。同时,售货员每种硬币数量都是无限的,用来找零。
要买价格为 (T) 的商品,求在交易中最少使用的硬币的个数(指的是交易中给售货员的硬币个数与找回的硬币个数之和)。
个数最多不能超过 (20000),如果不能实现,输出 (-1);否则输出此次交易中使用的最少的硬币个数。

样例

(3) 种硬币,面值分别为 (5, 25 50),个数分别为 (5, 2, 1),要买 (70) 的商品,不存在给小费的情况下,最少的硬币个数为 (3)
自己使用 (25)(50) 各一个,找回一个面值为 (5) 的硬币。

分析

  • 这个问题在普通背包的基础上,加入了找零的情况,很显然,如果自己拥有的硬币,即使恰好能购买商品,也不一定是使用硬币最少的,例如样例中,自己恰好买的话,使用硬币数为 (4),即 (5)(4) 个,(50)(1) 个,共 (5) 个。
  • 既然要求最后支出 (pay_{T+i}) 与找回 (back_i) 的硬币总和最少,即求 (min{pay_{T+i} + back_i})
  • 对于样例来说,我们还需要考虑:
    • (75) 使用的个数 + 找 (5) 的个数
    • (80) 使用的个数 + 找 (10) 的个数
    • ...
    • 其中有些数是达不到的,因此需要加判断。
  • 我们可以对自己的硬币跑多重背包,最大容量为 (20000)(pay_i) 表示恰好付钱为 (i) 的时候所需要的最好硬币个数;对售货员跑完全背包,(back_i) 表示找回 (i) 所需要的的最少硬币个数。最后扫一遍,最小化 (min{pay_{T+i} + back_i})

部分代码

还没顾上写;
原文地址:https://www.cnblogs.com/kuangbiaopilihu/p/12073070.html