题目连接 计蒜客
题意
买水,
给定 n 种水, 至少需要的水的重量 m
问 用最少的钱买尽量多的水 的钱数 和 水重量
题解
首先, 需要明确一点 买的水至少是m, 比如当m=5时,
3元 买 5单位
3元 买 6单位
3元 买 100单位
这时候答案是 3 100, 需要用尽量少的钱买尽量多的水
求最小花费好求, 只需要将递推数组初始化为无穷大, dp[0]初始化为0, 然后维护最大值即可
需要解决的问题是要记录尽量多的水重量,
首先, 递推一遍结束, dp[m]的确是最小花费, 并不一定唯一, 但只是买够 m单位水, 比如说上边例子,
dp[5] = 3;
dp[6] = 3;
dp[100] = 3;
这个时候, 需要找到尽量大的重量, 因为 dp[m] 的时候记录的虽然是最小花费, 但是只是 装满m的时候,
但是只是 装满m的时候,
但是只是 装满m的时候,
重要的话说三遍 !!!
当然会有装不满的可能, 比如 m = 5,
5元 6单位
4元 100单位
d[0] =0;
dp[1] = 0;
dp[2] = 0;
dp[3] = 0;
dp[4] = 0;
dp[5] = 6;
dp[6] = 0;
…
dp[10] = 12;
…
dp[`5] = 18;
…
等等等
…
dp[100] = 4;
重点来了, 背包递推到m, 前提是装满容量m的背包的最小价值
也就是说如果, 可能存在装不满背包的情况下, 水的花费更少, 获得的水重量更多
那么, 我们就只需要找 从 m 到 m加上最重的一件物品 中, 找最小花费对应的能买到的更多水数
遍历这个最大可能背包容量, 维护最小花费的同时记录最小花费时的背包容量
用题意来说就是, 遍历水的最大可能重量, 维护最小花费的同时记录最小花费能买到多少水
( 从小到大遍历, 相等的时候一定是更大的重量来覆盖了 )
代码
#include <bits/stdc++.h>
using namespace std;
#define sc scanf
#define pf printf
const int maxn = 1e3+10