Description
给定n个活动,活动ai表示为一个三元组(si,fi,vi),其中si表示活动开始时间,fi表示活动的结束时间,vi表示活动的权重, si<fi。带权活动选择问题是选择一些活动,使得任意被选择的两个活动ai和aj执行时间互不相交,即区间[si,fi)与[sj,fj) 互不重叠,并且被选择的活动的权重和最大。请设计一种方法求解带权活动选择问题。
Input
第一行输入M(M<=10)表示有M组数据。每组数据输入整数N(N<=10000), 接下来输入N个活动。
Output
输出M行正整数,第i行表示第i组数据的能够选择活动最大权值和。
代码如下
//
// Created by 86152 on 2023/12/2.
//
#include "iostream"
#include "algorithm"
#include "cstring"
using namespace std;
const int N = 10010;
struct Node {
int s;
int f;
int v;
bool operator<(Node &t) {
return s < t.s;
}
} node[N];
int main() {
int M;
cin >> M;
while (M--) {
int n;
int max_end_time = 0;
cin >> n;
for (int i = 0; i < n; ++i) {
cin >> node[i].s >> node[i].f >> node[i].v;
max_end_time = max(max_end_time, node[i].f);
}
sort(node, node + n); // 对活动进行排序
int f[N]; // f[i]表示最晚结束时间为i的最大价值
memset(f, 0, sizeof f); // 全部初始化为0
for (int i = 0; i < n; ++i) { // 遍历物品
for (int j = max_end_time; j >= node[i].f; j--) { // 遍历价值
f[j] = max(f[j], f[node[i].s] + node[i].v);
}
}
cout<<f[max_end_time]<<endl;
}
}