
uu我饿风格月完工腐恶跳舞额发他王启发对呀特王启发对呀特发乌鸦退费武器研发他无非无法推特乌鸦范玮琪放弃要他与非
关注引自免费微信小程序:皆我百晓生
这个问题可以通过贪心算法解决。我们需要找到一个方法来分配每个子任务的测试点数量,使得满足所有子任务的最少测试点要求,并且总测试点数不超过m。同时,我们要最大化最小的qi / pi 比率。
以下是详细的步骤:
qs 来存储每个子任务选择的测试点数。下面是一个C++实现:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
struct Subtask {
int Pi, Wi;
double priority;
bool operator<(const Subtask& other) const {
return priority > other.priority;
}
};
std::pair<int, int> gcd(int a, int b) {
if (b == 0) {
return {a, 1};
} else {
auto result = gcd(b, a % b);
return {result.second, result.first};
}
}
int main() {
int n, m;
std::cin >> n >> m;
std::vector<Subtask> tasks(n);
for (int i = 0; i < n; ++i) {
std::cin >> tasks[i].Pi >> tasks[i].Wi;
tasks[i].priority = static_cast<double>(tasks[i].Wi) / tasks[i].Pi;
}
std::sort(tasks.begin(), tasks.end());
std::vector<int> qs(n, 0);
int total_qi = 0;
for (auto& task : tasks) {
int qi = task.Wi;
while (total_qi + qi > m) {
--qs[qs.size() - 1];
total_qi -= qi;
}
total_qi += qi;
qs[tasks.size() - 1 - i] = qi;
}
if (total_qi < m) {
std::cout << "Zip file size too big after extraction.Poor M!\n";
} else {
int min_ratio_numerator = INT_MAX;
int min_ratio_denominator = INT_MAX;
for (int qi : qs) {
if (qi != 0 && qi < min_ratio_numerator * tasks[qs.size() - 1 - i].Pi) {
min_ratio_numerator = qi;
min_ratio_denominator = tasks[qs.size() - 1 - i].Pi;
}
}
auto gcd_result = gcd(min_ratio_numerator, min_ratio_denominator);
min_ratio_numerator /= gcd_result.first;
min_ratio_denominator /= gcd_result.first;
std::cout << min_ratio_numerator << "/" << min_ratio_denominator << "\n";
for (int qi : qs) {
std::cout << qi << " ";
}
std::cout << "\n";
}
return 0;
}
这段代码首先读取输入,然后创建一个结构体数组表示子任务及其优先级。接着进行排序,然后根据优先级分配测试点数。在分配过程中,如果超出限制,则回溯减少之前分配的测试点数。最后计算并输出最小的qi / pi比率以及对应的qi列表。