Educational Codeforces Round 137 (Rated for Div. 2) E. FTL

题意:

有两个激光炮,充能时间为 t t t,攻击力为 p p p,这两个炮要么是各打各的,也就是一个充能好就立即释放,要么其中一个充能完毕后等着另一个充能,然后一起释放。
有一个怪物血量为 h h h,防御力为 s s s。求最快击杀怪物的时间。

思路:

这个题启发挺大的。
首先我们的攻击怪物决策只有两种:
1.只要某种激光冷却完毕,就立即攻击。
2.等待两种激光均冷却完毕,发动攻击。
换句话说,在发动一次共同攻击之前:只要完成冷却,就立即攻击。
启发就是:发动攻击之后,二者又同时开始冷却,我们就又回到了最开始的子问题。
所以我们定义 d p [ i , j ] dp[i,j] dp[i,j]表示当前造成伤害 i i i,在上一次发动共同攻击之后,激光1又攻击了 j j j次。那么激光2的攻击次数我们也是可以算出来的:在 j ∗ t 1 j*t1 jt1的时间内尽可能多攻击。

code:

	LL p1, t1, p2, t2, h, s;
    cin >> p1 >> t1 >> p2 >> t2 >> h >> s;
    if(t1 > t2) {
        swap(t1, t2);
        swap(p1, p2);
    }
    vector<vector<LL>> f(5005, vector<LL>(5005, 1e16));
    f[0][0] = 0; //f[i][j]造成伤害i且上一次共同攻击之后激光1攻击了j次的时间
    LL ans = 1e16;
    for(int i = 0; i < h; i++) {
        for(int j = 0; j <= 5000; j++) {
            LL time = j * t1 % t2;
            time = t2 - time;
            //进行一次激光2,不进行激光1
            if(time < t1) {
                if(i + p2 - s >= h) ans = min(ans, f[i][j] + time);
            }
            if(time <= t1) {
                //进行激光1,期间可以进行激光2
                if(i + p1 - s + p2 - s >= h) ans = min(ans, f[i][j] + t1);
                else f[i + p1 - s + p2 - s][j + 1] = min(f[i + p1 - s + p2 - s][j + 1], f[i][j] + t1);
                //等待激光2, 二者再同时攻击
                if(i + p1 + p2 - s >= h) ans = min(ans, f[i][j] + t1);
                else f[i + p1 + p2 - s][0] = min(f[i + p1 + p2 - s][0], f[i][j] + t1);
            }
            if(time > t1) {
                //进行激光1 期间不可以进行激光1
                if(i + p1 - s >= h) ans = min(ans, f[i][j] + t1);
                else f[i + p1 - s][j + 1] = min(f[i + p1 - s][j + 1], f[i][j] + t1);
                //等待激光2, 二者再同时攻击
                if(i + p1 + p2 - s >= h) ans = min(ans, f[i][j] + time);
                else f[i + p1 + p2 - s][0] = min(f[i + p1 + p2 - s][0], f[i][j] + time);
            }
        }
    }

你可能感兴趣的:(线性dp,c++,算法)