BZOJ5224[Lydsy2017省队十连测] 毁灭

原题链接:https://www.lydsy.com/JudgeOnline/problem.php?id=5224

毁灭

Description

小S 的面前有一个Boss,Boss 具有n 的攻击力和m 的生命值,而小S 除了1 点生命值以外就穷得只剩钱了,所幸小S 可以用钱购买能力,具体来说,她可以以价格a 购买1 点攻击力,以价格b 购买1 点防御力,以价格c 购买一点生命值,此外,小S 是一个熟练的膜法师,所以她可以以价格d 购买一点膜法值。战斗开始时,首先小S 以时间的力量对Boss 造成等同于膜法值的伤害,之后由Boss 先手,双方轮流对对方造成Max(己方攻击-对方防御,0)的伤害,直到一方生命值非正,判定另一方获胜。现在小S 想知道,她若想战胜Boss 至少需要多少钱。

注意,Boss 防御力为0。T不大于1e5,n, m不大于2*1e5

Input

第一行一个整数T 表示测试数据组数。

接下来T 行,每行六个正整数n m a b c d,含义如上,这些数均不超过1e8。

N,M<=200000 T<=10^5

Output

T 行,每行一个整数表示对应的答案。

Sample Input

2
9 5 6 9 6 4
5 6 3 8 3 6

Sample Output

20
33

题解

先想想暴力,攻击力的值域为 [ 0 , m ] [0,m] [0,m],防御力值域为 [ 0 , n ] [0,n] [0,n],膜法值值域为 [ 0 , m ] [0,m] [0,m],只有生命值不好枚举,但是在已知前 3 3 3个量之后我们就可以直接计算生命值了,复杂度为 O ( T × n m 2 ) O(T\times nm^2) O(T×nm2)

让我们考虑一下防御值对生命值与防御值代价的影响,设 b o s s boss boss的攻击次数为 t t t,当前防御值为 d e f , d e f ∈ [ 0 , n ] def,def\in[0,n] def,def[0,n],就有:
c o s t = t × ( n − d e f ) × c + d e f × b = t × n × c + ( b − t × c ) d e f cost=t\times (n-def)\times c+def\times b\\ =t\times n\times c+(b-t\times c)def cost=t×(ndef)×c+def×b=t×n×c+(bt×c)def

因为 d e f def def的收益为线性,所以取值只可能为 0 0 0 n n n,而当 d e f = n def=n def=n时,我们并不需要多余的攻击力,可以直接特判 a t k = 1 , d e f = n atk=1,def=n atk=1,def=n的情况,综上我们在实际计算时只需要考虑 d e f = 0 def=0 def=0的情况。

现在我们的枚举项只有 a t k atk atk(攻击力)和 o r z orz orz(膜法值)了,考虑一下这两者间的关系:
如果 o r z orz orz的代价小于等于 a t k atk atk,我们就直接全买膜法开局秒杀 b o s s boss boss
如果 o r z + = a t k orz+=atk orz+=atk后少挨了一次打,减少生命值支出后更划算,我们就可以一直 o r z + = a t k orz+=atk orz+=atk,最后变成全膜法;
如果前两种情况都不满足,我们就只维持最低的膜法,就是消掉 m   %   a t k m\ \%\ atk m % atk这一零碎部分,要不然干脆余数也不消了,直接砍死。
综上,对于膜法,我们要么直接特判一炮轰死,要不然就在枚举过程中讨论消余数和直接砍死的情况。

所以我们只用枚举 a t k atk atk就行了,我们需要考虑的只有 ⌈ m a t k ⌉ \lceil\frac{m}{atk}\rceil atkm不同的 m \sqrt{m} m 个取值,最终复杂度 O ( T × m ) O(T\times \sqrt{m}) O(T×m )

代码
#include<cstdio>
#define min(a,b) (a<b?a:b)
int T,n,m,l,r,t;
long long a,b,c,d,ans;
void in(){scanf("%d%d%lld%lld%lld%lld",&n,&m,&a,&b,&c,&d);}
void ac()
{
	for(ans=min(m*d,a+n*b),l=1,r,t;l<=m;l=r+1)t=m/l,r=m/t,ans=min(ans,min((t+1)*c*n+l*a,t*c*n+(m-t*r)*d+r*a));
	printf("%lld\n",ans);
}
main(){for(scanf("%d",&T);T--;)in(),ac();}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ShadyPi

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

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

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

打赏作者

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

抵扣说明:

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

余额充值