实验任务
小八同学最近爱上了吃零食,但是他又想追求健康的生活。每一包零食都有一个能量值,小八同学每次都一定要吃总能量刚好为\(v\)的零食才肯罢休。而且小八同学又很懒,他希望通过吃数量最少的零食达到这个目的。所以他希望你能设计一个程序帮他决定要吃哪些零食。
给定每种零食所包含的能量和数目,你的任务是给出所要吃的零食的最小数目。
数据输入
先输入一行包含 2 个整数\(v\ (v\leq 20000)\)、\(n\),表示小八需要吃能量值和为\(v\)的零食,而零食一共有\(n\)种,下面输入\(n\)行,每行 2 个整数,第一个表示该种零食的能量值(能量值大于 0),第二个表示该种零食的总数。所有零食的总数量不会超过 50。
数据输出
输出一行包含一个整数表示小八最少需要吃的零食数量,若小八无法通过吃零食达到\(v\)的能量值,则输出“Fail”。
输入示例 | 输出示例 |
---|---|
10 2 4 1 2 10 |
4 |
10 2 4 1 7 3 |
Fail |
源代码
1 |
|
设计思路与复杂度分析
此题为多重背包问题,具体请参考背包九讲第1-3讲。做法是将第\(i\)种物品分成了\(log C_i\)种物品,将原问题转化为复杂度为\(O(V\times \sum log C_i)\)的 01 背包问题。
本题实现的时候已经将01背包、多重背包、完全背包均包括了。如果遇到类似题目可以直接从中举一反三。
附多重背包问题通用描述:有\(N\)种物品和一个容量为\(V\)(本题为总能量\(m\))的背包。第\(i\)种物品最多有\(C_i\)件可用,每件耗费的空间是\(V_i\),价值是\(W_i\)(本题价值为1,即占用1 个数量)。求解将哪些物品装入背包可使这些物品的耗费的空间总和不超过(刚好等于)背包容量,且价值总和最大(最小)。
关于0x7f的说明:由于\(memset\)函数是来自\(string.h\)库的函数,所以其操作对象为字节,将\(int\)数组按字节初始化为0x7f,实际得到的是0x7f7f7f7f。已经几乎达到了\(int\)的极限。不存在两个极大值相加的情况可以这样初始化,如果存在两个极大值相加的情况可以初始化为0x3f,其为0x7f的一半。