Educational Codeforces Round 125 (Rated for Div. 2) D
D
首先明确题意
是每次组建的一支队伍中的兵来自同一种种类,这样简化了很多题意
容易发现,如果\(\frac{h_{i}}{D}> \frac{H}{\frac{C}{c_i}*d_i}\),那么答案就一定存在,反之如果所有i (\(i\in [1,n]\)) 都不满足,那么输出-1
确定答案存在的同时还需要取最小值
确定算法
暴力:O(n*m) 必然超时
接下来容易想到二分
但是怎么二分是个问题 qwq
第一种二分:
对于每一组输入的H,D,二分答案,check函数里面枚举[1,n],看是否有一组满足
时间复杂度 O(mlog(C)n) 对于每个怪物,进行logC次n的遍历
甚至不如暴力算法,我是傻逼才会想这么写
第二种二分:
设val[i]为花费为i时的最大伤害
那么我想到了这么写
for(int i=1;i<=n;i++){
for(int j=c[i];j<=C;j+=c[i]){
val[j]=max(val[j],d[i]*h[i]*(j/c[i]));
}
}
for(int i=1;i<=C;i++){
val[i]=max(val[i],val[i-1]);
}
可以优化为O(nlog)级别的了!
然而,因为\(c_i\)值的不确定,第一段代码可能会达到O(C*C)的时间复杂度,依然超时
第三种二分(正解):
设val[i]为花费为i时的最大伤害
另外一种优化方式:真ClogC级别
for(int i=1;i<=n;i++){
scanf("%lld%lld%lld",&c[i],&d[i],&h[i]);
val[c[i]]=max(val[c[i]],d[i]*h[i]);
}
for(int i=1;i<=C;i++){
for(int j=i;j<=C;j+=i){
val[j]=max(val[j],val[i]*(j/i));
}
}
for(int i=1;i<=C;i++){
val[i]=max(val[i],val[i-1]);
}
代码参考dalao,学习了
总结
二分是个好算法,希望大家都能学会

浙公网安备 33010602011771号