Codeforces Round 894 (Div. 3) F. Magic Will Save the World 【DP枚举的艺术】

背包问题变式

我们先来看原文题解

First, let’s note that Vika can defeat all the monsters at once, in the last second. There is no point in spending mana gradually.
Now, let’s say we know how many seconds Vika will accumulate mana before spending it. Then we also know how much mana she will have accumulated by that time. How should she spend it?
Note that the total strength of the monsters is given to us. Therefore, it is enough for us to spend as much of the available water mana as possible, so that there is enough fire mana left for the remaining monsters. This is a well-known knapsack problem.
Finally, let’s note that we don’t need to iterate over the number of seconds and build the knapsack each time. It is enough to build it initially, and then iterate over how much water mana we will spend and whether we will have enough fire mana left for the rest.

提取一下关键信息

  1. 我们不需要去规划在什么时候用魔法,因为最后可以把魔法一口气用完
  2. 我们目标是要求第几秒,但是如果给你秒数,你也很难有个策略把水魔法和火魔法完美的分配到每个怪物身上
  3. 假设所有怪物的力量之和是SUM,要明确的是,一定存在一部分A,会被水魔法击败,另外的一部分的B,会被火魔法击败。
  4. 如果我们已知被水魔法击败的怪物力量之和A_SUM, 就可以推出时间,从而推断出B_SUM,就能得到我们花了多少时间
  5. 关键就在这里,枚举的艺术!! 我们可以用dp背包的经典套路,得到怪物血量之和的组合是否存在
  6. 我们最后再从0开始枚举所有血量,即A_SUM,得到最后的情况!
#include 
typedef long long ll;
using namespace std;
const int N = 1e8;
void solve()
{
    ll w, f;
    cin >> w >> f;
    int n;
    cin >> n;
    vector<int> v(n + 1);
    ll sum = 0;
    for (int i = 1; i <= n; i++)
    {
        cin >> v[i];
        sum += v[i];
    }
    vector<int> dp(sum + 1);
    dp[0] = 1;
    for (int i = 1; i <= n; i++)
    {
        for (int j = sum; j >= v[i]; j--)
        {
            dp[j] |= dp[j] || dp[j - v[i]];
        }
    }
    ll res = LLONG_MAX;
    for (int i = 0; i <= sum; i++)
    {
        if (dp[i])
        {
            res = min(res, max((i + w - 1) / w, (sum - i + f - 1) / f));
        }
    }
    cout << res << "\n";
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int t;
    cin >> t;
    while (t--)
    {
        solve();
    }
}

你可能感兴趣的:(codeforces,算法,c++,数据结构)