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
分析:这道题目,一看好像是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; } }