通过软盘拷贝文件 - 华为OD统一考试

OD统一考试(B卷)

分值: 200分

题解: Java / Python / C++

题目描述

有一名科学家想要从一台古董电脑中拷贝文件到自己的电脑中加以研究但此电脑除了有一个3.5寸软盘驱动器以外,没有任何手段可以将文件持贝出来,而且只有一张软盘可以使用,因此这一张软盘是唯一可以用来拷贝文件的载体。

科学家想要尽可能多地将计算机中的信息拷贝到软盘中,做到软盘中文件内容总大小最大。已知该软盘容量为1474560字节。文件占用的软盘空间都是按块分配的,每个块大小为512个字节。一个块只能被一个文件使用。拷贝到软盘中的文件必须是完整的,且不能采取任何压缩技术。

输入描述

第1行为一个整数N,表示计算机中的文件数量。1≤ N < 1000。

第2行到第N+1行(共N行),每行为一个整数,表示每个文件的大小 s i s_i si,单位为字节.0 < i < N,0< s i s_i si< 1000000

输出描述

科学家最多能拷贝的文件总大小。

备注

为了充分利用软盘空间,将每个文件在软盘上占用的块记录到本子上。即真正占用软盘空间的只有文件内容本身。

示例1

输入:
3
737270
737272
737288

输出:
1474542

题解

这个问题是经典的01背包 问题可以使用动态规划来解决。

软盘块容量相当于背包的容量,文件的大小相当于价值。

代码思路

定义一个一维数组dp,其中dp[vol]表示在软盘容量为vol块的情况下,科学家最多能拷贝的文件总大小。初始时,将所有元素初始化为0。

接下来,对于每个文件的大小,计算它所占的块数,即block = ceil(size / 512),然后使用动态规划更新dp数组。

具体的更新方式是:

  • 对于每个vol,如果vol >= block,则更新dp[vol] = max(dp[vol], dp[vol - block] + size)。这表示在软盘容量为vol块的情况下,科学家可以选择拷贝当前文件,也可以选择不拷贝当前文件,取两者之间的最大值。

最终,dp[BLOCK_VOLUME]即为科学家最多能拷贝的文件总大小。

Java

java 复制代码
import java.util.Scanner;
/**
 * @author code5bug
 */
public class Main {
    public static void main(String[] args) {
        // 软盘容量的块数
        int BLOCK_VOLUME = 1474560 / 512;
        Scanner scanner = new Scanner(System.in);

        // 读取文件数量
        int n = scanner.nextInt();
        // 存储每个文件的大小
        int[] sizes = new int[n];
        for (int i = 0; i < n; i++) {
            sizes[i] = scanner.nextInt();
        }

        int[] dp = new int[BLOCK_VOLUME + 1];
        for (int size : sizes) {
            int block = (int) Math.ceil((double) size / 512);  // 存储文件所占的块数
            for (int vol = BLOCK_VOLUME; vol >= block; vol--) {
                dp[vol] = Math.max(dp[vol], dp[vol - block] + size);
            }
        }

        System.out.println(dp[BLOCK_VOLUME]);
    }
}

Python

python 复制代码
# 软盘的块数
from math import ceil

# 软盘容量的块数
BLOCK_VOLUME = 1474560 // 512
n = int(input())
# 存储每个文件的大小
sizes = [int(input()) for _ in range(n)]


dp = [0] * (BLOCK_VOLUME + 1)
for size in sizes:
    block = ceil(size / 512)  # 存储文件所占的块数
    for vol in range(BLOCK_VOLUME, block - 1, -1):
        dp[vol] = max(dp[vol], dp[vol - block] + size)

print(dp[BLOCK_VOLUME])

C++

cpp 复制代码
#include <iostream>
#include <vector>

using namespace std;

int main() {
    // 软盘容量的块数
    const int BLOCK_VOLUME = 1474560 / 512;
    int n;
    cin >> n;

    // 存储每个文件的大小
    vector<int> sizes(n);
    for (int i = 0; i < n; ++i) {
        cin >> sizes[i];
    }

    // dp数组初始化
    vector<int> dp(BLOCK_VOLUME + 1, 0);

    for (int size : sizes) {
        // 存储文件所占的块数
        int block = (size - 1) / 512 + 1;
        for (int vol = BLOCK_VOLUME; vol >= block; --vol) {
            dp[vol] = max(dp[vol], dp[vol - block] + size);
        }
    }

    cout << dp[BLOCK_VOLUME] << endl;

    return 0;
}

相关练习题

题号 题目 难易
LeetCode 416 416. 分割等和子集 中等
LeetCode 474 474. 一和零 中等
LeetCode 494 494. 目标和 中等

🙏整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

相关推荐
IT猿手7 分钟前
超多目标优化:基于导航变量的多目标粒子群优化算法(NMOPSO)的无人机三维路径规划,MATLAB代码
人工智能·算法·机器学习·matlab·无人机
Java知识技术分享14 分钟前
使用LangChain构建第一个ReAct Agent
python·react.js·ai·语言模型·langchain
Erik_LinX17 分钟前
算法日记25:01背包(DFS->记忆化搜索->倒叙DP->顺序DP->空间优化)
算法·深度优先
Alidme24 分钟前
cs106x-lecture14(Autumn 2017)-SPL实现
c++·学习·算法·codestepbystep·cs106x
奔跑吧邓邓子24 分钟前
【Python爬虫(44)】分布式爬虫:筑牢安全防线,守护数据之旅
开发语言·分布式·爬虫·python·安全
小王努力学编程25 分钟前
【算法与数据结构】单调队列
数据结构·c++·学习·算法·leetcode
最遥远的瞬间26 分钟前
15-贪心算法
算法·贪心算法
非 白34 分钟前
【Java】单例模式
java·笔记·单例模式
IDRSolutions_CN1 小时前
如何在 PDF 文件中嵌入自定义数据
java·经验分享·pdf·软件工程·团队开发
程序员 小濠1 小时前
接口测试基础 --- 什么是接口测试及其测试流程?
自动化测试·python·测试工具·职场和发展·appium·接口测试·压力测试