zoukankan      html  css  js  c++  java
  • Educational Codeforces Round 91 (Rated for Div. 2) D. Berserk And Fireball

    题目链接:https://codeforces.com/contest/1380/problem/D

    题意

    给出一个大小为 $n$ 的排列 $a$ 和一个序列 $b$,有两种操作:

    • 花费 $x$ 消除连续 $k$ 个数
    • 花费 $y$ 选取两个相邻的数,消除较小的数

    问能否将 $a$ 变为 $b$,以及最小花费。

    题解

    如果序列 $b$ 中元素的出现顺序与 $a$ 不一致,则无解。

    否则根据 $b$ 将 $a$ 分割为一个个区间,对每一个区间进行单独操作。

    对于一个长度小于 $k$ 的区间:

    • 如果区间最大值大于两端的分割点,则无解
    • 否则花费为 $size imes y$ 

    对于一个长度大于等于 $k$ 的区间:

    如果区间最大值大于两端的分割点,则必须使用一次操作一

    • 如果操作一花费较小,花费为 ${lfloor frac{size}{k} floor} imes x + size \% k imes y$
    • 如果操作二花费较小,花费为 $x + (size - k) imes y$

    如果区间最大值小于两端的分割点,则可不必使用操作一

    • 如果操作一花费较小,花费为 ${lfloor frac{size}{k} floor} imes x + size \% k imes y$
    • 如果操作二花费较小,花费为 $size imes y$

    代码

    #include <bits/stdc++.h>
    using ll = long long;
    using namespace std;
    int main() {
        ll n, m, x, k, y; cin >> n >> m >> x >> k >> y;
        int a[n] = {};
        int pos[n] = {};
        for (int i = 0; i < n; i++) {
            cin >> a[i];
            --a[i];
            pos[a[i]] = i;
        }
        int b[m] = {};
        int mx_pos = 0;
        bool skip[n] = {}; //记录在 a 中的分割点
        for (int i = 0; i < m; i++) {
            cin >> b[i];
            --b[i];
            if (pos[b[i]] < mx_pos) {
                cout << -1 << "
    ";
                return 0;
            } else mx_pos = pos[b[i]];
            skip[b[i]] = true;
        }
        vector<vector<int>> v; //存储每个区间
        vector<pair<int, int>> border; //存储每个区间两端的分割点
        vector<int> t; //每个区间
        int l = -1, r = -1; //左右端点
        for (int i = 0; i < n; i++) {
            if (skip[a[i]]) { //如果遇到区间分割点
                if (l == -1 and r == -1) { //第一个区间只有右端点
                    r = a[i];
                } else { //之后区间的左端点为上一个区间的右端点
                    l = r;
                    r = a[i];
                }
                if (t.size() > 0) {
                    v.push_back(t);
                    border.emplace_back(l, r);
                    t.clear();
                }
                continue;
            }
            t.push_back(a[i]);
        }
        if (t.size() > 0) {
            l = r;
            v.push_back(t);
            border.emplace_back(l, -1);
            t.clear();
        }
        ll ans = 0;
        for (int i = 0; i < v.size(); i++) {
            bool seg_mx = *max_element(v[i].begin(), v[i].end()) > max(border[i].first, border[i].second);
            if (v[i].size() < k) {
                if (seg_mx) {
                    cout << -1 << "
    ";
                    return 0;
                }
                ans += v[i].size() * y;    
            } else {
                if (seg_mx) 
                    ans += min(x + (v[i].size() - k) * y, v[i].size() / k * x + v[i].size() % k * y);
                else
                    ans += min(v[i].size() * y, v[i].size() / k * x + v[i].size() % k * y);
            }
        }
        cout << ans << "
    ";
    }
  • 相关阅读:
    hihoCoder #1179 : 永恒游戏 (暴力枚举)
    HDU 5269 ZYB loves Xor I (二分法)
    HDU 5268 ZYB loves Score (简单模拟,水)
    acdream 1683 村民的怪癖(KMP,经典变形)
    acdream 1686 梦醒(时钟重合)
    acdream 1685 多民族王国(DFS,并查集)
    acdream 1681 跳远女王(BFS,暴力)
    HDU 5265 pog loves szh II (技巧)
    HDU 5264 pog loves szh I (字符串,水)
    HDU 1023 Train Problem II (卡特兰数,经典)
  • 原文地址:https://www.cnblogs.com/Kanoon/p/13296712.html
Copyright © 2011-2022 走看看