hdu5931 Mission Possible(枚举+最值)

题目

一个人从起点出发,要走距离D,

每秒他会持续受到A点伤害(即不是直接在这秒开始或结束统一扣血,是在这1s内均摊的),

初始血量H=0,速度V=0,每秒生命回复R=0(每秒末回复R点生命值,瞬时回血而非持续)。

提升一点血量、速度、生命回复的花费分别为G1、G2、G3。

要求走到终点的过程中,生命值不能小于0(可以等于0),

且提升速度不能超过D,问最小花费是多少。

1 <= D,A <= 500000, 1 <= G1, G2, G3 <= 200

思路来源

https://blog.csdn.net/qq_31759205/article/details/81951609

题解

虽然题面很长,但其实是个很水的题,

首先由速度不能超过D,想到枚举速度1到D,

枚举速度v,从起点到终点的时间t就固定下来了,

在速度上的花费v*G[2]①也确定下来了,

血量应至少为A,否则第一秒就死了,花费为A*G[1]②

 

剩余的时间为D/v-1,考虑回血和初始血量满足条件两种情形,

回血,只需满足R==A即可,花费为A*G[3]③,

初始血量够,还需血量A*(D/v-1),血量需向上取整,花费为A*(D/v-1)*G[1]③

 

枚举v,取一个①+②+③的最小值即可,式子可进一步化简

心得

诶,平时跟榜跟习惯了,有的时候丧失自己独立思考的能力了

感觉赛后补题很重要啊,培养自己在很少人做出来的情况下,独立开榜的思维和能力

注意,这种线性规划题取G[1]和G[3]往往具有单增或单减性质,

即最值只可能在两个端界取得,不可能在中间取得

即可化简为形如a+b=定值sum,求z=X*a+Y*b的最值的类型

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int T;
ll D,A,g[4];
ll t,ans;
int main()
{
	scanf("%d",&T);
	for(int cas=1;cas<=T;cas++)
	{
		ans=4e18;
		scanf("%lld%lld",&D,&A);
		for(int i=1;i<=3;++i)
		scanf("%lld",&g[i]);
		for(ll v=1;v<=D;++v)
		ans=min(ans,v*g[2]+min((A*D+v-1)/v*g[1],(g[1]+g[3])*A));
		printf("Case #%d: %lld\n",cas,ans);
	}
	return 0;
} 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Code92007

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值