The problem involves selecting a subset of computers and fulfilling orders to maximize profit, under constraints on core count and clock frequency.
Each computer provides a certain number of cores at a cost and has a minimum required clock frequency. Each order yields revenue but requires a specific number of cores and can only be processed on computers with sufficient clock frequency.
A key insight is to unify computers and orders into a single sequence of items and apply a modified 0-1 knapsack approach. Computers are treated as negative-value items (costs), while orders are positive-value items (revenues). To respect the clock frequency constraint, all items are sorted in descending order of frequency. When frequencies are equal, comptuers precede orders—ensuring that cores are acquired before they are consumed.
Let dp[j] represent the maximum profit achievable with j available cores. The array is initialized to negative infinity except for dp[0] = 0.
Processing each item:
- For a computer with
ccores and costv(stored as negative): iteratejfrom current max cores down to 0, and udpatedp[j + c] = max(dp[j + c], dp[j] + v). - For an order requiring
Ccores and yielding valueV: iteratejfrom 0 tocurrent_max_cores - C, and updatedp[j] = max(dp[j], dp[j + C] + V).
The variable total_cores tracks the cumulative core capacity from selected computers to bound the inner loops efficiently.
Finally, the answer is the maximum value in the dp array across all possible core counts.
#include <bits/stdc++.h>
using namespace std;
const int MAX_ITEMS = 4010;
const int MAX_CORES = 100010;
struct Item {
int cores, freq, value;
void read(int sign) {
cin >> cores >> freq;
int price; cin >> price;
value = sign * price;
}
bool operator<(const Item& other) const {
if (freq != other.freq) return freq > other.freq;
return value < other.value; // computers (negative) come before orders
}
};
long long dp[MAX_CORES];
Item items[MAX_ITEMS];
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
cin >> n;
for (int i = 0; i < n; ++i) items[i].read(-1);
cin >> m;
for (int i = n; i < n + m; ++i) items[i].read(1);
sort(items, items + n + m);
fill(dp, dp + MAX_CORES, LLONG_MIN);
dp[0] = 0;
int total_cores = 0;
for (int i = 0; i < n + m; ++i) {
if (items[i].value < 0) { // computer
for (int j = total_cores; j >= 0; --j) {
if (dp[j] != LLONG_MIN) {
dp[j + items[i].cores] = max(dp[j + items[i].cores], dp[j] + items[i].value);
}
}
total_cores += items[i].cores;
} else { // order
for (int j = 0; j <= total_cores - items[i].cores; ++j) {
if (dp[j + items[i].cores] != LLONG_MIN) {
dp[j] = max(dp[j], dp[j + items[i].cores] + items[i].value);
}
}
}
}
cout << *max_element(dp, dp + total_cores + 1) << '\n';
return 0;
}