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.

63 lines
1.9 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 110; // 能量石个数上限
const int M = 10010; // 能量上限
// 用来描述每个能量石的结构体
struct Node {
int s; // 吃掉这块能量石需要花费的时间为s秒
int e; // 可以获利e个能量
int l; // 不吃的话每秒失去l个能量
} q[N]; // 能量石的数组
// 结构体对比函数
bool cmp(const Node &a, const Node &b) {
return a.s * b.l < b.s * a.l;
}
int n; // 能量石的数量
int f[M]; // f[i]:花i个时间得到的最大能量
int idx; // 输出是第几轮的测试数据
int main() {
// T组测试数据
int T;
scanf("%d", &T);
while (T--) {
// 初始化为负无穷,预求最大,先设最小
memset(f, -0x3f, sizeof f);
scanf("%d", &n);
// 总时长,背包容量
int m = 0;
int res = 0;
// 读入数据
for (int i = 1; i <= n; i++) {
scanf("%d %d %d", &q[i].s, &q[i].e, &q[i].l);
m += q[i].s;
}
// 贪心排序
sort(q + 1, q + 1 + n, cmp);
// 01背包,注意恰好装满时的状态转移方程的写法
// 不能是至多j,而是恰好j
// 这是因为如果时间越长,不见得获取的能量越多,因为能量石会损耗掉
// 恰好的,最终需要在所有可能的位置去遍历一次找出最大值
// 每次清空状态数组
memset(f, 0, sizeof f);
for (int i = 1; i <= n; i++) {
int e = q[i].e, s = q[i].s, l = q[i].l;
for (int j = m; j >= s; j--) {
int w = e - (j - s) * l;
f[j] = max(f[j], f[j - s] + w);
res = max(res, f[j]);
}
}
printf("Case #%d: %d\n", ++idx, res);
}
return 0;
}