勇者游戏(game)

题目描述
小刚最近在玩一个勇者游戏。他将操作一个勇者角色一路过关斩将击败若干怪兽。这个游戏有n个关卡组成,每一个关卡勇者都需要和一个怪兽战斗。
战斗的规则是这样的:勇者和怪兽各有一个生命值和攻击力,采用轮流攻击的形式,勇者先攻击,被攻击会损失对应攻击力的生命值,直到有一方阵亡为止。特别的: 勇者的生命值在每一个关卡结束后不会恢复,而是继续带到下一个关卡。
勇者的生命值并不会一直够用,如果勇者生命值降低到0及以下,那么游戏就会gameover。不过,勇者拥有一个生命道具,可以恢复一定数值的生命值,并拥有一个使用次数上限P(过关不会恢复使用次数)。而且,在每一关使用该道具恢复的生命值是不同的。(勇者的生命值没有上限) 每通过一个关卡,小刚就会获得一定的分数,分数为过关时勇者的剩余生命值乘上该关卡的一个得分系数V。
现在小刚处在第一关,他的勇者具有H点生命值和A点攻击力。小刚事先查阅了攻略,得知了每一个关卡怪兽的生命值hi,攻击力ai,和使用道具能恢复的生命值pi,以及得分系数vi。现在,小刚想要知道,他要如何操作,才可以尽可能达到后面的关卡。同时,在保证尽可能达到后面的关卡的基础上,小刚想知道他能获得的最大分数。

输入描述
输入第一行三个整数n,H,A,P。分别表示关卡数和勇者初始的生命值、攻击力,勇者生命恢复道具能够使用的次数。

接下来n行,每行4个整数hi,ai,pi,vi,依次表示每个关卡的怪兽生命值、攻击力,使用生命道具能恢复的生命值,以及该关卡的得分系数。

输出描述
输出两行,第一行一个整数表示能够通过的最大关卡。第二行一个整数表示在通过最大关卡数的情况下能够获得的最大分数。

样例输入
3 20 5 2
8 2 1 1
10 10 10 3
6 4 2 2
样例输出
3
150
说明/提示
对于100的数据1<=n<=100,1<=P<=20,1<=H,A,hi,ai,pi<=100,1<=vi<=10(4次方)。

特别地,对于20的数据,P=1。

#include<bits/stdc++.h>
#define m memset(f,-1,sizeof(f))
using namespace std;
struct guan {
	int h, a, p, v, kou;
}guanka[110];
int f[110][2110][25];
int n, H, A, P, ans, maxH, maxguan;
int main(){
	int m1=0;
	scanf("%d%d%d%d",&n,&H,&A,&P);
	for (int i=1;i<=n;i++) {
		scanf("%d%d%d%d",&guanka[i].h,&guanka[i].a,&guanka[i].p,&guanka[i].v);
		guanka[i].kou = guanka[i].a * (guanka[i].h / A);
		if (guanka[i].h % A == 0) guanka[i].kou -= guanka[i].a;
		m1 = max(m1, guanka[i].p);
	}
	maxH = m1 * P + H;
	m;
	f[0][H][P] = 0;
	for (int i=1;i<=n;i++) {
		for (int j=1;j<=maxH;j++) {
			for (int k=0;k<=P;k++) {
				if (f[i-1][j][k] == -1) continue;
				for (int l=0;l<=k;l++) {
					if (guanka[i].kou >= j + l * guanka[i].p) continue;
					int newh = j + l * guanka[i].p - guanka[i].kou;
					f[i][newh][k-l] = max(f[i][newh][k-l], f[i-1][j][k] + guanka[i].v * newh);
					maxguan = i;
				}
			}
		}
	}
	ans = 0;
	for (int j=1;j<=maxH;j++) {
		ans = max(ans, f[maxguan][j][0]);
	}
	printf("%d\n%d\n", maxguan, ans);
	return 0;
}

  • 10
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值