Constraints
Time Limit: 1 secs, Memory Limit: 32 MB
Description
ZEH是一名04级的学生,他除了绩点高,还有运动细胞。有一次学院举办运动会,ZEH发现里面的项目都是他所向披靡的,当然他想获得所有项目的No1,但是一个人的精力总是有限的,ZEH也是只有P(Power的简写,一个大于0且小于1000的整数)的精力。如果精力足够参加比赛,一定能赢;相反,精力不够去参加比赛,Loss的概率很大,ZEH当然不想因为Loss而不爽。
整个运动会有N(大于0且小于等于100)项比赛,每项比赛都是在指定的一天D(D大于等于0)内举行完,但是一天可能同时有多个比赛同时进行,ZEH当然就不能同时兼顾。比赛结束后,院长都会亲自为冠军颁发一定数额的奖金,其他名次只有一张奖状。ZEH当然是冲着奖金去的,他想获得最多的奖金,师弟师妹们,你能帮ZEH大牛计算出他最多能拿多少奖金吗?
Input
第一行是一个整数T,表示这题有T个用例。
每个用例的第一行有两个正整数P N,分别表示ZEH的精力和比赛的项目。
第二行到第N+1行是N个项目,每一行有三个正整数D E M,分别表示这个项目在第D天举行,需要E的精力,和比赛的奖金。项目的顺序都按D排好序。
Output
对于每个用例,输出他能拿的最多的奖金。
Sample Input
1 14 5 0 3 7 0 2 5 1 4 2 2 6 14 2 8 15
Sample Output
23
简单的分组背包问题,状态转移是f[k][w] = max(f[k-1][w], f[k-1][w-c[i]] + w) for every i in c;
注意数据中e可能为0,而且天数可能是不连续的。(PS:因为这个WA了四次)
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
int f[1005];
vector<int> bag_e[105], bag_m[105];//用vector来分组放物品
int main()
{
int t;
cin >> t;
while (t--)
{
int p, n, d, e, m, cur = 0;
memset(f, 0, sizeof(f));
for (int i = 0; i < 105; ++i) bag_e[i].resize(0), bag_m[i].resize(0);
cin >> p >> n;
for (int i = 0; i < n; ++i)
{
cin >> d >> e >> m;
bag_e[d].push_back(e);
bag_m[d].push_back(m);
cur = d;
}
for (int i = 0; i < 105; ++i)
{
for (int w = p; w >= 0; --w)
{
int t = f[w];//写成一维数组形式的时候要注意是e为0的情况
for (int k = 0; k < bag_e[i].size(); ++k) if (bag_e[i][k] <= w)
t = max(t, f[w-bag_e[i][k]] + bag_m[i][k]);
f[w] = t;
}
}
cout << f[p] << endl;
}
return 0;
}