ZigZagK的博客
[数学]Codeforces1435E【Solo mid Oracle】题解
2020年10月26日 17:22
查看标签

题目概述

你有一种法术 $a,b,c,d$ ,在 $t$ 时刻使用时将对敌人造成 $a$ 伤害,但是在 $[t+1,t+c]$ 秒时敌人将每秒回复 $b$ 的血量,并且下一次释放时间至少是 $t+d$ 。如果不间断(冷却好马上使用)的施放法术,求能干掉的敌人的最大血量。

解题报告

建议这题和C题互换……这样应该更多人做出来。

首先显然 $a>bc$ 时,就可以干掉任意血量的敌人,所以我们考虑 $a\le bc$ 的情况。

由于间隔时间为 $d$ ,回血持续时间为 $c$ ,假设当前还有 $x$ 次之前的回血存在,则 $x\le\lfloor{c\over d}\rfloor$ 。在 $x>\lfloor{c\over d}\rfloor$ 之后,之前残留的回血效果就维持在 $\lfloor{c\over d}\rfloor$ 次不变,由此可以发现只要 $a\le bc$ ,就不可能干掉任意血量的敌人。

现在的问题就是取一个 $x$ ,使得伤害值最高,写一下式子:

$$ (x+1)a-{(d+xd)x\over 2}b=(x+1)a-{(x+1)x\over 2}db\\ =-{1\over 2}dbx^2+(a-{1\over 2}db)x+a $$

就是个二次函数……求下对称轴左右两边的整数值就行了。

示例程序

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;typedef long double DB;

int te;LL a,b,c,d;

LL F(LL x) {return (x+1)*a-x*(x+1)/2*d*b;}
int main(){
    for (scanf("%d",&te);te;te--){
        scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
        if (a>b*c) {puts("-1");continue;}
        DB A=(DB)-d*b/2,B=a-(DB)d*b/2;
        LL x=-B/(A*2);
        printf("%lld\n",max(a,max(F(x),F(x+1))));
    }
    return 0;
}
版权声明:本博客所有文章除特别声明外,均采用 CC BY 4.0 CN协议 许可协议。转载请注明出处!