NC14553 小明打联盟(完全背包+贪心)

大意:

小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时间和固定的伤害值为:

1.乌鸦坐飞机 释放时间:x 固定伤害值:a

2.蜘蛛吃耳屎 释放时间:y 固定伤害值:b

3.饿狼前进 释放时间:z 固定伤害值:c

他还有一个大招,其释放的时间是一个区间【L,R】,可以在区间内任意时间点释放出技能,其如果在L+i时刻释放技能,其能够打出的伤害值为:temp+A*i

这里temp值表示技能的基础伤害(同时也就是在时刻L释放技能的伤害值),A是一个常数。

小明很喜欢研究连招使得在有限的时间内打出最高的伤害,现在他想要在T长度单位时间内打出最高的伤害,问这个最大伤害值。

思路:

可以想到利用完全背包,将大招化作R-L个物品,但是这样就变成n^2的复杂度,会超时

进一步考虑,因为大招的伤害是线性递增的,所以你要么选择不蓄力直接放,要么选择蓄满力再放,这样就把R-L个物品化成了2个物品

但是最后不一定能一直蓄满力再放大招,所以只需要最后枚举一下R-L长度的时间即可

#include <bits/stdc++.h>

using namespace std;

const int N = 4e5 + 5;
typedef long long LL;
LL T, x, a, y, b, z, c, L, R, temp, A, f[N];
struct node {
    LL v, w;
};
vector<node> aa;
bool cmp(node a, node b) { return a.v < b.v; }
int main() {
    while (cin >> T >> x >> a >> y >> b >> z >> c >> L >> R >> temp >> A) {
        memset(f, 0, sizeof f);
        aa.clear();
        aa.push_back({x, a});
        aa.push_back({y, b});
        aa.push_back({z, c});
        aa.push_back({L, temp});
        aa.push_back({R, temp + A * (R - L)});
        for (LL i = 0; i < aa.size(); i++) {
            for (LL j = aa[i].v; j <= T; j++) {
                f[j] = max(f[j], f[j - aa[i].v] + aa[i].w);
            }
        }
        for (LL i = L; i <= R; i++)
            f[T] = max(f[T], f[T - i] + temp + A * (i - L));
        cout << f[T] << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/dyhaohaoxuexi/p/14493237.html