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
【思路】
比较直接的分组背包问题,但是写起来比较啰嗦,当时记得是参考了某位牛人的思路写的。
1 #include<iostream> 2 #include<memory.h> 3 #include<vector> 4 #include<algorithm> 5 using namespace std; 6 7 struct Match 8 { 9 int d; 10 int e; 11 int m; 12 Match (int dd,int ee,int mm) 13 { 14 d=dd; 15 e=ee; 16 m=mm; 17 } 18 }; 19 int main() 20 { 21 int t; 22 cin>>t; 23 while(t--) 24 { 25 int p,n,now,last,sum=0; 26 cin>>p>>n; 27 vector<Match> mat[n+1]; 28 int D,E,M; 29 if(n==1) 30 { 31 sum=1; 32 cin>>D>>E>>M; 33 mat[1].push_back(Match(D,E,M)); 34 } 35 else 36 { 37 cin>>D>>E>>M; 38 mat[1].push_back(Match(D,E,M)); 39 sum=1; 40 last=D; 41 for(int i=1; i<n; i++) 42 { 43 cin>>D>>E>>M; 44 now=D; 45 if(now==last) 46 { 47 mat[sum].push_back(Match(D,E,M)); 48 } 49 else 50 { 51 sum++; 52 mat[sum].push_back(Match(D,E,M)); 53 } 54 last=D; 55 } 56 sum++; 57 } 58 59 int f[sum+1][p+1]; 60 memset(f,0,sizeof(f)); 61 62 for(int i=1; i<=sum; i++) 63 for(int v=p; v>=0; v--) 64 { 65 f[i][v]=f[i-1][v]; 66 for(int kk=0;kk<mat[i].size();kk++) 67 { 68 if(v-mat[i][kk].e>=0) 69 f[i][v]=max(f[i][v],f[i-1][v-mat[i][kk].e]+mat[i][kk].m); 70 } 71 } 72 cout<<f[sum][p]<<endl; 73 } 74 }