[sicily]1750. 运动会

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、输入的第D天,这些D值不一定是连续的,2、输入的E,即需要消耗的能量,可能是0。


#include <iostream>
#include <algorithm>
using namespace std;

int main()
{   
    int t;
    int f[1000],d[100],w[100],v[100];
    cin>>t;
    while(t--)
    {
        int p,n,index=0;  
        int day[100]={0};
        memset(f,0,sizeof(f));
        memset(d,0,sizeof(d));
        cin>>p>>n;
        for(int i=0; i<n; i++)
        {
            cin>>d[i]>>w[i]>>v[i];          
        }
        day[0] = 1;//根据天数分组,统计好每天的比赛个数
        for(int i=1; i<n; i++)
        {
            if(d[i] != d[i-1])
                index++;
            day[index]++;
        }
        int count = 0;
        for(int i=0; i<=index; i++)
        {   
            count = count + day[i];   
            for(int j=p; j>=0; j--)
            {   
                int curr = f[j];             
                for(int k=0; k<day[i]; k++)
                {
                    int tmp = count - day[i] + k ; //一维数组存放的,需要找到第i 天第k 项所对应的index。
                    if( j>= w[tmp] && curr < f[j-w[tmp]]+v[tmp])
                        curr = f[j-w[tmp]]+v[tmp];
                }
                f[j] = curr; 
            }
        }
        cout<<f[p]<<endl;       
    }   
    //system("pause");
    return 0;   
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值