题目描述
Johnny 成立了 Bytecomp,一个提供云计算能力的公司。这样的公司通常拥有许多快速计算机,客户可以在其上进行计算。
但是 Johnny 还没有购买任何计算机。于是他前往一家计算机商店,收到了包含全部
台可用的计算机的清单。
每台计算机都可以用三个属性描述:处理器的核心数量
,时钟频率
以及价格
。每台计算机包含
个不会互相干扰的核心,所以它们可以被分配给不同的任务。
当客户订购资源时,她会指定所需的核心数
以及所需的最低时钟频率
,订单还包含客户愿意支付的价格
。
如果接受了一份订单,Bytecomp 需要提供对客户所需的算力的专用访问权。Johnny 需要选择
个核心(可能来自不同的计算机),且它们的时钟频率至少为
,这些核心不能被分配给其它订单。
请你帮助 Johnny 赚取尽可能多的利润:接受一部分客户订单,并购买商店中的一部分计算机,以满足所有接受了的订单的需求。
你的目标是最大化总利润,即为客户提供算力的收入与购买计算机的成本之间的差值。
输入格式
第一行一个整数
(
),表示商店中可用的计算机的台数。
接下来
行,每行描述一台计算机,包含三个整数
(
,
,
),分别表示核心数,时钟频率和价格。
接下来一行一个整数
(
),表示客户的订单总数。
接下来
行,每行描述一个订单,包含三个整数
(
,
,
),分别表示需要的核心数,最低时钟频率以及预算。
输出格式
仅一行一个整数,表示能够获得的最大总利润。
样例
样例输入
4
4 2200 700
2 1800 10
20 2550 9999
4 2000 750
3
1 1500 300
6 1900 1500
3 2400 4550
样例输出
350
分析
此题很容易发现是01背包(选或不选),不妨把买的和卖的合为同一类型(将一些变量转负)。不过这道题细节很多,本蒟蒻交了十次才AC…请读者在阅读核心代码时仔细想一想边界。
代码
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <climits>
#include <cstring>
#define LL long long
using namespace std;
const int MAXN = 4005, MAXX = 100005;
const LL lmi = LONG_LONG_MIN;
struct Node {
int C, F, V;
}arr[MAXN];
int n, m, sum;
LL dp[MAXX];//剩余j个核心数的最大价值
bool vis[MAXX];
bool cmp(Node x, Node y) {
if(x.F != y.F) {
return x.F > y.F;
}
return x.V < y.V;
}
int main() {
LL ans = 0;
scanf("%d", &n);
for(int i = 1; i <= n; i ++) {
scanf("%d%d%d", &arr[i].C, &arr[i].F, &arr[i].V);
arr[i].V = -arr[i].V;
}
scanf("%d", &m);
for(int i = n + 1; i <= n + m; i ++) {
scanf("%d%d%d", &arr[i].C, &arr[i].F, &arr[i].V);
arr[i].C = -arr[i].C;
}
sort(arr + 1, arr + 1 + n + m, cmp);
for(int i = 1; i <= 100005; i ++) {
dp[i] = lmi;
}
vis[0] = 1;
for(int i = 1; i <= n + m; i ++) {
if(arr[i].V < 0) {
sum += arr[i].C;
for(int j = sum; j >= arr[i].C; j --) {
if(!vis[j - arr[i].C]) continue;
vis[j] |= vis[j - arr[i].C];
dp[j] = max(dp[j], dp[j - arr[i].C] + arr[i].V);
}
}
else {
for(int j = 0; j <= sum + arr[i].C; j ++) {
if(!vis[j - arr[i].C]) continue;
vis[j] |= vis[j - arr[i].C];
dp[j] = max(dp[j], dp[j - arr[i].C] + arr[i].V);
}
}
}
for(int i = 0; i <= sum; i ++) {
if(vis[i]) ans = max(ans, dp[i]);
}
printf("%lld", ans);
return 0;
}