0
点赞
收藏
分享

微信扫一扫

2829: 闯关游戏【DP】

捡历史的小木板 2022-05-03 阅读 64
算法

时间限制: 1 Sec 内存限制: 64 MB

题目描述

小i正在玩一个闯关游戏,游戏一共n关。
初始的时候小i有H点体力以及0个金币。
小i只能按从第1关到第n关按顺序完成。在第i关时,小i要在三种操作中选择一种:
1.当前体力不小于Ai
可以选择这个操作,消耗Ai点体力,获得Bi个金币。
2.当前体力不小于Ci可以选择这个操作,消耗Ci点体力Di个金币。
3.结束游戏,直接结算。
当小i完成全部n个关卡后会自动结束游戏,进行结算。
结算时小i最多获得了多少金币?

输入

第一行一个正整数T表示数据组数。
对于每组数据,第一行输入两个正整数n,H,分别表示关卡数量和初始体力值。
接下来n行,每行输入4个正整数Ai,Bi,Ci,Di。T≤2000,1≤n,H,Ai,Bi,Ci,Di≤6000,∑n+H≤150000,仅有6组数据满足n,H>100

输出

对于每组数据输出一行,表示小i最多能得到多少金币。

样例输入

样例输出

代码

//博客 
#include "stdio.h"
#include "string.h"
#include "algorithm"
#include "iostream"
using namespace std;
int z[6009];
int main()
{
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	int t;
	cin>>t;
	while(t--)
	{
		int n,h;
		int a,b,c,d;
		cin>>n>>h;
		int sum=0,f=0,now=0;
		memset(z,0,sizeof(z));
		while(n--)
		{
			cin>>a>>b>>c>>d;
			if(f)	continue;
			if(a>c)
			{
				swap(a,c);
				swap(b,d);
			}
			if(a>h)
			{
				f=1;
				continue;
			}
			h-=a,now+=b;//每次消耗最少体力
			c-=a,d-=b;
			for(int i=h;i>=c;i--)
				z[i]=max(z[i],z[i-c]+d);
			sum=max(sum,now+z[h]);
		}
		printf("%d\n",sum);
	}
}

举报

相关推荐

0 条评论