CF1743 E - FTL(线性DP)

E - FTL(线性DP)

题意

​ 现在你有两支激光枪,枪A伤害为p1,冷却时间为t2;枪B伤害为p2,冷却时间为t2。敌人的护甲为s,可以抵消每一次攻击中的s点伤害。请问最快造成h(h5000)伤害的时间是多少。

思路

​ 如果将A和B一起发射,那么将造成(p1+p2s),对于单独的发射,为pis。那么我们就知道,有时候需要单独发射,有时候需要齐射。易知这是一个动态规划问题。考虑到h比较小,可以设置状态f[i]为造成i点伤害花费的最小时间。

​ 第一步,我们可以得到一个简单的转移,也就是当前伤害为i是由上一次单独发射枪A或者枪B的而来的。但是这个情况就没有考虑到齐射的情况,我们现在就需要思考如何转移齐射的情况。枚举伤害是5e3,所以我们还可以通过O(n)的时间来枚举齐射。由于1ti,所以我们可以枚举一下让枪A射j轮,且最后一轮是齐射;以及让枪B射j轮,且最后一轮为齐射。那么转移方程就已经出来了,再初始化为正无穷,设f0=0,问题可解。

对于齐射的转移,我们可以看做在发动一次齐射之前,两者的策略就是:只要冷却时间一结束,就马上发起攻击。

实现

​ 我们会发现在前几个阶段递推的时候,下标会变负。假设我们的伤害都为5,那么f1,f2,f3...这几个状态都是第一次独射得来的。所以我们直接将下标与0取一个max就可以了。

#define int long long
const int N = 5005;
int f[N];
int p1, p2, t1, t2;
int h, s;
 
void solve()
{
    cin >> p1 >> t1 >> p2 >> t2;
    cin >> h >> s;
    
    memset(f, 0x3f, sizeof f);
    f[0] = 0;
    for(int i = 1; i <= h; i ++)
    {
        f[i] = min(f[max(0ll, i - (p1 - s))] + t1, f[max(0ll, i - (p2 - s))] + t2);
        for(int j = 1; j <= i; j ++)
        {
            if(t1 * j >= t2)
            {
                int dmg = (j - 1) * (p1 - s) + (t1 * j - t2) / t2 * (p2 - s) + (p1 + p2 - s);
                f[i] = min(f[i], f[max(0ll, i - dmg)] + t1 * j);
            }
            if(t2 * j >= t1)
            {
                int dmg = (j - 1) * (p2 - s) + (t2 * j - t1) / t1 * (p1 - s) + (p1 + p2 - s);
                f[i] = min(f[i], f[max(0ll, i - dmg)] + t2 * j);
            }
        }
    }
    cout << f[h] << '\n';
}
posted @   DM11  阅读(82)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示
主题色彩