欢迎光临
我们一直在努力

题解:学而思编程 小明的U盘

本文分享的必刷题目是从蓝桥云课、洛谷、AcWing等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。

欢迎大家订阅我的专栏:算法题解:C++与Python实现!

附上汇总贴:算法竞赛备考冲刺必刷题(C++) | 汇总


【题目来源】

学而思编程:小明的U盘

【题目描述】

在 2202 年的某一天,小明得到了一个高端 U 盘。

但是小明发现这个 U 盘有一些问题:

这个 U 盘的传输接口大小是

L

L

L,只能传输大小不超过

L

L

L 的文件。

这个 U 盘容量是

S

S

S,一共只能装不超过

S

S

S 的文件。

但是他要备份的资料却有很多,你只能备份其中的一部分。

共有

n

n

n 个文件,第

i

i

i 个文件的大小和价值为

w

i

,

v

i

w_i,v_i

wi,vi。小明很快发现他不可能把所有文件装进优盘,好在这是一个高端的 U 盘,他可以花钱升级接口大小、或者升级容量。每花

1

1

1 元可以将接口大小增加

1

1

1,每花

1

1

1 元可以将 U 盘容量增加

1

1

1

注意:你的文件不能被分割(你只能把一个文件整个的传输进去,并储存在U盘中),你放在 U 盘中文件的总大小不能超过 U 盘容量。

现在问题来了:小明只有

m

m

m 元,他想知道,他最多可能将多大价值的文件放入 U 盘中。

【输入】

1

1

1 行,

4

4

4 个正整数

n

,

m

,

L

,

S

n,m,L,S

n,m,L,S

2

2

2 行,

n

n

n 个正整数

w

1

,

w

2

,

,

w

n

w_1,w_2,⋯ ,w_n

w1,w2,,wn

3

3

3 行,

n

n

n 个正整数

v

1

,

v

2

,

,

v

n

v_1,v_2,⋯ ,v_n

v1,v2,,vn

【输出】

1

1

1 个整数,最多可以放入 U 盘的文件总价值。

【输入样例】

5 9 4 4
6 9 9 5 6
8 7 9 1 5

【输出样例】

9

【核心思想】

  • 问题分析:给定

    n

    n

    n 个文件(大小

    w

    i

    w_i

    wi,价值

    v

    i

    v_i

    vi),U盘初始接口大小

    L

    L

    L、容量

    S

    S

    S,预算

    m

    m

    m 元。每花1元可将接口或容量增加1。文件大小必须同时满足:不超过接口大小(才能传输)和不超过U盘容量(才能存储)。可以选择升级接口使某个大文件能够传输,求在预算内能装入的最大总价值。这是一个01背包变体问题,关键在于枚举哪个文件享受接口升级优惠。

  • 算法选择:

    • 01背包:dp[i][j] 表示前

      i

      i

      i 个文件,花费不超过

      j

      j

      j 的最大价值

    • 枚举优惠券使用:排序后枚举哪个文件使用接口升级
  • 关键步骤:

    • 按大小排序:将文件按

      w

      i

      w_i

      wi 从小到大排序,保证枚举时前面文件都能通过当前接口

    • 01背包DP:总可用资金 = 初始容量

      S

      S

      S + 预算

      m

      m

      m

      • dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i])(选或不选第

        i

        i

        i 个文件)

    • 枚举升级使用:对于排序后的第

      i

      i

      i 个文件:

      • 升级接口后的实际大小:cost = max(w[i] – L, 0)(升级后大小为

        L

        L

        L,原大小

        w

        [

        i

        ]

        w[i]

        w[i] 需要升级

        w

        [

        i

        ]

        L

        w[i]-L

        w[i]L

      • 剩余容量给其他文件:S + m – cost
      • 答案更新:ans = max(ans, dp[i][S + m – cost])
  • 时间/空间复杂度:

    • 时间复杂度:

      O

      (

      n

      ×

      (

      S

      +

      m

      )

      +

      n

      log

      n

      )

      O(n \\times (S+m) + n \\log n)

      O(n×(S+m)+nlogn),排序

      O

      (

      n

      log

      n

      )

      O(n \\log n)

      O(nlogn),背包

      O

      (

      n

      ×

      (

      S

      +

      m

      )

      )

      O(n \\times (S+m))

      O(n×(S+m))

    • 空间复杂度:

      O

      (

      n

      ×

      (

      S

      +

      m

      )

      )

      O(n \\times (S+m))

      O(n×(S+m))

  • 01背包变体(带优惠券抵扣)的核心思想:

    • 排序预处理:按文件大小排序,确保枚举时前面文件都能通过当前接口大小
    • 枚举策略:枚举哪个文件使用接口升级优惠,其余文件使用普通容量
    • 费用计算:升级接口后的实际占用 = max(原大小 – 接口大小, 0)
    • 容量分配:总资源 = 初始容量 + 预算,分配给升级文件和普通文件
    • 适用于带单一优惠选择的背包问题
  • 【算法标签】

    #01背包

    【代码详解】

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 505;
    int n, m, l, s, dp[N][20005], ans; // dp: 背包DP数组, ans: 最终答案
    struct node
    {
    int w, v; // w: 原价, v: 价值
    } a[N];

    // 按原价从小到大排序
    bool cmp(node x, node y)
    {
    return x.w < y.w;
    }

    int main()
    {
    cin >> n >> m >> l >> s;
    for (int i = 1; i <= n; i++)
    {
    cin >> a[i].w; // 读取原价
    }
    for (int i = 1; i <= n; i++)
    {
    cin >> a[i].v; // 读取价值
    }
    sort(a + 1, a + n + 1, cmp);

    // 0/1背包:计算前i个物品,花费不超过j的最大价值
    for (int i = 1; i <= n; i++)
    {
    for (int j = 1; j <= s + m; j++) // 总可用资金 = 初始资金s + 优惠券价值m
    {
    dp[i][j] = dp[i 1][j]; // 不选第i个物品
    if (j >= a[i].w)
    {
    // 选第i个物品
    dp[i][j] = max(dp[i][j], dp[i 1][j a[i].w] + a[i].v);
    }
    }
    }

    // 枚举使用优惠券购买的商品i
    for (int i = 1; i <= n; i++)
    {
    // 使用优惠券后的实际花费:原价 – 优惠券价值l,但不能为负
    int cost = max(a[i].w l, 0);
    ans = max(ans, dp[i][s + m cost]);
    }
    cout << ans;
    return 0;
    }

    【运行结果】

    5 9 4 4
    6 9 9 5 6
    8 7 9 1 5
    9

    赞(0)
    未经允许不得转载:171主机测评 » 题解:学而思编程 小明的U盘
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址