sicily1750. 运动会

来源:互联网 发布:java 字符串split 编辑:程序博客网 时间:2024/04/25 04:19

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

114 50 3 70 2 51 4 22 6 142 8 15

Sample Output

23
    分析:这道题目,一看好像是DP问题,认真看下去,确实是DP问题,只不过这个DP问题比一般的背包问题稍微复杂一点点,这个是背包问题的延伸。
    可以这样来理解题目意思,首先按照精力DP,内部循环是每一天的DP,每一天里面又包括多个活动,故每一天里面也要进行一次枚举,把所有的活动都过一遍。
    处理这道题目的关键,首先要读懂题目意思,知道这是一道DP问题,然后,设计好实用的数据结构。最后,实现起来就比较简单了。

#include <iostream>#include <cstring>#include <string>#include <stdio.h>#include <vector>#include<memory.h>using namespace std;struct Node{    int power[101];    int money[101];    int size;};int max(int a, int b) {    if (a >= b) {        return a;    }    else        return b;}int main() {    int t;    scanf("%d", &t);    int p, n, d, e, m;    while (t --) {        scanf("%d%d", &p, &n);        Node node;        int md = -1;        int tempsize;        vector<Node> myv;        for (int i = 1; i <= n; ++ i) {            scanf("%d%d%d", &d, &e, &m);            if (md != d) {                md = d;                tempsize = 0;                node.power[tempsize] = e;                node.money[tempsize] = m;                node.size = 1;                myv.push_back(node);            }            else if (md == d) {                //node = myv[d]                tempsize = myv[myv.size() - 1].size;                myv[myv.size() - 1].power[tempsize] = e;                myv[myv.size() - 1].money[tempsize] = m;                ++ myv[myv.size() - 1].size;            }        }        int dp[p + 1][myv.size() + 1];        memset(dp, 0, sizeof(dp));//cout << myv.size() << endl;        for (int i = 1; i <= p; ++ i) {            for (int j = 1; j <= myv.size(); ++ j) {                //cout << "www" << j << endl;                int maxu = -9;                for (int k = 0; k < myv[j - 1].size; ++ k) {                    if (myv[j - 1].power[k] <= i) {                        dp[i][j] = max (dp[i][j - 1], dp[i - myv[j - 1].power[k]][j - 1] + myv[j - 1].money[k]);                            //cout <<"a "<< i << " " << j << " " << dp[i][j] << endl;                            if (dp[i][j] > maxu) {                                maxu = dp[i][j];                            }                    }                    else {                        dp[i][j] = dp[i][j - 1];                        //cout <<"b "<< i << " " << j << " " << dp[i][j] << endl;                        if (dp[i][j] > maxu) {                                maxu = dp[i][j];                            }                    }                                }                dp[i][j] = maxu;            }        }               cout << dp[p][myv.size()] << endl;    }}                                 


原创粉丝点击