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.
|
|
#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; }
|