[CF1380D] Berserk And Fireball - 贪心

Description

有 n 个战士,第 i 个战斗力为 ai,操作有两种:消耗 x 点法力来干掉连续的恰好 k 个;消耗 y 点法力,让相邻两个决斗,战力较弱的被干掉。希望将序列从 a1..an 变成 b1..bm,求需要的最小法力值。保证 a 中元素是两两不同的。

Solution

考虑每一段需要删掉的数,如果数量小于 k 个,那么只能用 y 来消去,此时如果这一段的最大值大于两端点的最大值就无解

如果数目不少于 k,那么一定有解。

\(yk<x\) 时,如果这一段的最大值大于两端点的最大值就用一次 x,剩下的都是 y;否则全用 y。

\(yk \ge x\) 时,用几次 y,然后用 x。

#include <bits/stdc++.h>
using namespace std;

#define int long long

signed main()
{
    ios::sync_with_stdio(false);
    int n, m;
    cin >> n >> m;
    int x, k, y;
    cin >> x >> k >> y;
    vector<int> a(n + 2);
    a[0] = -1e9;
    a[n + 1] = -1e9;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    vector<int> p(n + 2);
    for (int i = 1; i <= n; i++)
        p[a[i]] = i;
    vector<int> b(m + 2);
    for (int i = 1; i <= m; i++)
        cin >> b[i];
    int ans = 0;
    for (int i = 0; i <= m; i++)
    {
        int l = b[i];
        int r = b[i + 1];
        if (l > 0)
            l = p[l];
        else
            l = 0;
        if (r > 0)
            r = p[r];
        else
            r = n + 1;
        int len = r - l - 1;
        if (len < 0)
        {
            cout << -1;
            return 0;
        }
        else
        {
            int mx = 0;
            for (int i = l + 1; i <= r - 1; i++)
                mx = max(mx, a[i]);
            if (len < k)
            {

                if (mx > a[l] && mx > a[r])
                {
                    cout << -1;
                    return 0;
                }
                else
                {
                    ans += len * y;
                }
            }
            else
            {
                if (y * k < x)
                {
                    if (mx > a[l] && mx > a[r])
                    {
                        ans += x + y * (len - k);
                    }
                    else
                    {
                        ans += y * len;
                    }
                }
                else
                {
                    ans += y * (len % k) + x * (len / k);
                }
            }
        }
    }
    cout << ans;
}

相关文章: