大厂笔试题
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

72 lines
2.7 KiB

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 日志文件结构体
struct LogFile {
int process; // 进程序号
int size; // 文件大小
int downloads; // 下载次数
};
int main() {
int N, M, C;
cin >> N >> M >> C;
vector<vector<LogFile>> logs(N); // 每个进程的日志文件
// 读取日志文件信息
for (int i = 0; i < N * M; ++i) {
int process, size, downloads;
cin >> process >> size >> downloads;
logs[process].push_back({process, size, downloads});
}
int minCapacity = 0; // 最少需要的容量
vector<int> mustHaveDownloads; // 每个进程必须要保存的日志文件的下载次数
vector<pair<int, int>> optionalFiles; // 额外的日志文件,保存 {文件大小,下载次数}
// 选择每个进程的最小日志文件,并记录额外的文件
for (int i = 0; i < N; ++i) {
// 找到当前进程中最小的文件
int minSize = 21, minDownloads = 0;
for (const auto& log : logs[i]) {
if (log.size < minSize) {
minSize = log.size;
minDownloads = log.downloads;
}
}
// 计算最少需要的容量
minCapacity += minSize;
mustHaveDownloads.push_back(minDownloads);
// 记录下当前进程中非最小的日志文件,作为可选的日志文件
for (const auto& log : logs[i]) {
if (log.size != minSize || log.downloads != minDownloads) {
optionalFiles.push_back({log.size, log.downloads});
}
}
}
// 如果最小容量已经超出了U盘容量,返回-1
if (minCapacity > C) {
cout << -1 << endl;
return 0;
}
// 计算每个进程必须保存的文件的下载次数之和
int totalDownloads = 0;
for (int d : mustHaveDownloads) {
totalDownloads += d;
}
// 剩余的U盘容量
int remainingCapacity = C - minCapacity;
// 动态规划数组,dp[j] 表示容量为 j 时的最大下载次数
vector<int> dp(remainingCapacity + 1, 0);
// 0-1 背包:选择可选的日志文件
for (const auto& file : optionalFiles) {
int size = file.first;
int downloads = file.second;
for (int j = remainingCapacity; j >= size; --j) {
dp[j] = max(dp[j], dp[j - size] + downloads);
}
}
// 最大的下载次数等于已选择的最小文件的下载次数 + 背包中选出的最大下载次数
int maxDownloads = totalDownloads + dp[remainingCapacity];
// 输出结果
cout << maxDownloads << endl;
return 0;
}