[BZOJ5224]毁灭

[BZOJ5224]毁灭_第1张图片

  • 菜的真实,今天打膜泥赛,想了半天只想到了 ( T n 2 ) (Tn^2) (Tn2)的暴力做法,30分本来觉得还可以了,神仙直接 A A A了,自闭了。
  • 30分:我们发现 O r z Orz Orz(膜法值)、 a t k atk atk(攻击力)、 d e f def def(防御值)都是有枚举的范围的,而生命值没有。不过假如我们知道了前三个,生命值自然可以确定。枚举一个 O r z Orz Orz,再枚举一个 a t k atk atk,那么我们就知道了攻击有多少次。假设 b o s s boss boss攻击 t t t次,那么对于防御和生命的花费
    c o s t = d e f ∗ b + ( n − d e f ) ∗ t ∗ c cost=def*b+(n-def)*t*c cost=defb+(ndef)tc
    = d e f ( b − t c ) + n ∗ t ∗ c =def(b-tc)+n*t*c =def(btc)+ntc
  • 即def的花费是线性的,那么显然 d e f def def只有取 0 0 0和取 n n n两种情况。30分有了。
  • 继续深入思考,对于def取n的情况,显然我们只需要再购买1个 a t k atk atk就好了。
  • 对于 d e f def def 0 0 0,假如 O r z Orz Orz的代价小于 a t k atk atk,那么一次性秒杀 b o s s boss boss一定是最优的。当 O r z Orz Orz代价大于 a t k atk atk时, O r z Orz Orz的作用在于适当选取让自己少挨一次锤,从而减少生命的花费。那么此时我们需要枚举一个攻击次数,对于相同的攻击次数来说,肯定是攻击力最小的最优。对于通过增加 O r z Orz Orz来减少一次挨打来减小代价,一定是同一攻击次数里攻击力最大的那一个。考虑攻击力更小一点的,因为 O r z Orz Orz代价比攻击力代价大,所以显然没有变的更优。所以可以数论分块,每次两种情况尝试更新最优值。复杂度 O ( T n ) O(T\sqrt{n}) O(Tn )

C o d i n g Coding Coding

#include
#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;
}

你可能感兴趣的:(比赛)