题目
题目描述
本题为改编题。
发鸠之山,其上多柘木。有鸟焉,其状如乌,文首,白喙,赤足,名曰精卫,其名自詨。是炎帝之少女,名曰女娃。女娃游于东海,溺而不返,故为精卫。常衔西山之木石,以堙于东海。——《山海经》
精卫终于快把东海填平了!只剩下了最后的一小片区域了。同时,西山上的木石也已经不多了。精卫能把东海填平吗?
事实上,东海未填平的区域还需要至少体积为 的木石才可以填平,而西山上的木石还剩下 块,每块的体积和把它衔到东海需要的体力分别为 和 。精卫已经填海填了这么长时间了,她也很累了,她还剩下的体力为 。
输入格式
输入文件的第一行是三个整数:。
从第二行到第 行分别为每块木石的体积和把它衔到东海需要的体力。
输出格式
输出文件只有一行,如果精卫能把东海填平,则输出她把东海填平后剩下的最大的体力,否则输出 Impossible
(不带引号)。
样例 #1
样例输入 #1
100 2 10
50 5
50 5
样例输出 #1
0
样例 #2
样例输入 #2
10 2 1
50 5
10 2
样例输出 #2
Impossible
提示
数据范围及约定
- 对于 的数据,;
- 对于 的数据,;
- 对于 的数据,,所有读入的数均属于 ,最后答案不大于 。
解题
方法一:背包DP
思路
把搬运每块石头所需的体力看作费用,每块石头的体积看作价值,做 01背包 ,则 表示所用体力为 时,能搬运的最大总体积。
接下来枚举 ,第一个使得 的 就是能把东海填满所需的最少体力,输出 即可。如果不存在这样的体力则说明无法填满,输出 Impossible
即可。
代码
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 1e4 + 10;
int v, n, c;
int f[N];
int main() {
scanf("%d%d%d", &v, &n, &c);
for (int i = 0; i < n; ++i) {
int vol, nrg;
scanf("%d%d", &vol, &nrg);
for (int j = c; j >= nrg; --j) {
f[j] = max(f[j], f[j - nrg] + vol);
}
}
for (int i = 0; i <= c; ++i) {
if (f[i] >= v) {
printf("%d\n", c - i);
return 0;
}
}
puts("Impossible");
return 0;
}
评论区