侧边栏壁纸
博主头像
GabrielxD

列車は必ず次の駅へ。では舞台は?私たちは?

  • 累计撰写 674 篇文章
  • 累计创建 128 个标签
  • 累计收到 20 条评论

目 录CONTENT

文章目录

【背包DP】精卫填海

GabrielxD
2023-09-29 / 0 评论 / 0 点赞 / 137 阅读 / 781 字
温馨提示:
本文最后更新于 2023-09-29,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

题目

P1510 精卫填海


题目描述

本题为改编题。

发鸠之山,其上多柘木。有鸟焉,其状如乌,文首,白喙,赤足,名曰精卫,其名自詨。是炎帝之少女,名曰女娃。女娃游于东海,溺而不返,故为精卫。常衔西山之木石,以堙于东海。——《山海经》

精卫终于快把东海填平了!只剩下了最后的一小片区域了。同时,西山上的木石也已经不多了。精卫能把东海填平吗?

事实上,东海未填平的区域还需要至少体积为 vv 的木石才可以填平,而西山上的木石还剩下 nn 块,每块的体积和把它衔到东海需要的体力分别为 kkmm。精卫已经填海填了这么长时间了,她也很累了,她还剩下的体力为 cc

输入格式

输入文件的第一行是三个整数:v,n,cv,n,c

从第二行到第 n+1n+1 行分别为每块木石的体积和把它衔到东海需要的体力。

输出格式

输出文件只有一行,如果精卫能把东海填平,则输出她把东海填平后剩下的最大的体力,否则输出 Impossible(不带引号)。

样例 #1

样例输入 #1

100 2 10
50 5
50 5

样例输出 #1

0

样例 #2

样例输入 #2

10 2 1
50 5
10 2

样例输出 #2

Impossible

提示

数据范围及约定

  • 对于 20%20\% 的数据,0<n500<n \le 50
  • 对于 50%50\% 的数据,0<n10000<n \le 1000
  • 对于 100%100\% 的数据,0<n1040<n \le 10^4,所有读入的数均属于 [0,104][0,10^4],最后答案不大于 cc

解题

方法一:背包DP

思路

把搬运每块石头所需的体力看作费用,每块石头的体积看作价值,做 01背包 ,则 f[i]f[i] 表示所用体力为 ii 时,能搬运的最大总体积。

接下来枚举 f[0c]f[0 \dots c],第一个使得 f[i]vf[i] \ge vii 就是能把东海填满所需的最少体力,输出 cic - i 即可。如果不存在这样的体力则说明无法填满,输出 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;
}
0

评论区