Sicily 1750 运动会

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;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值