- 菜的真实,今天打膜泥赛,想了半天只想到了
(Tn2)的暴力做法,30分本来觉得还可以了,神仙直接
A了,自闭了。
- 30分:我们发现
Orz(膜法值)、
atk(攻击力)、
def(防御值)都是有枚举的范围的,而生命值没有。不过假如我们知道了前三个,生命值自然可以确定。枚举一个
Orz,再枚举一个
atk,那么我们就知道了攻击有多少次。假设
boss攻击
t次,那么对于防御和生命的花费
cost=def∗b+(n−def)∗t∗c
=def(b−tc)+n∗t∗c
- 即def的花费是线性的,那么显然
def只有取
0和取
n两种情况。30分有了。
- 继续深入思考,对于def取n的情况,显然我们只需要再购买1个
atk就好了。
- 对于
def为
0,假如
Orz的代价小于
atk,那么一次性秒杀
boss一定是最优的。当
Orz代价大于
atk时,
Orz的作用在于适当选取让自己少挨一次锤,从而减少生命的花费。那么此时我们需要枚举一个攻击次数,对于相同的攻击次数来说,肯定是攻击力最小的最优。对于通过增加
Orz来减少一次挨打来减小代价,一定是同一攻击次数里攻击力最大的那一个。考虑攻击力更小一点的,因为
Orz代价比攻击力代价大,所以显然没有变的更优。所以可以数论分块,每次两种情况尝试更新最优值。复杂度
O(Tn
)。
Coding
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int t,n,m,a,b,c,d;
ll ans;
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d%d%d%d%d",&n,&m,&a,&b,&c,&d);
ans=1e17;int l,r,t;
for(ans=min(1LL*n*b+a,1LL*m*d),l=1,r;l<=m;l=r+1){
t=m/l;r=m/t;ans=min(ans,min(1LL*t*n*c+1LL*(m-r*t)*d+1LL*a*r,1LL*(t+1)*n*c+1LL*a*l));
}
printf("%lld\n",ans);
}
return 0;
}