公式

B - 商品選抜 / Product Selection 解説 by MMNMM 印刷ページ


この問題は、並べることができる商品の販売価格を計算しておき、これの大きいほうからたかだか \(K\) 個の合計を求めればよいです。

並べることができる商品が \(K\) 個に満たない場合に注意してください。

実装例は以下のようになります。

#include <iostream>
#include <vector>
#include <algorithm>
#include <ranges>
using namespace std;

int main() {
    int N, M, K, Q;
    cin >> N >> M >> K >> Q;

    // それぞれの区画にある商品の販売価格
    vector<vector<int>> merchandise(M);
    for (int i = 0; i < N; ++i) {
        int V, C;
        cin >> V >> C;
        --C;
        merchandise[C].emplace_back(V);
    }

    // 並べられる商品の販売価格の一覧
    vector<int> available_merchandise;
    for (int i = 0; i < Q; ++i) {
        int S;
        cin >> S;
        --S;
        ranges::copy(merchandise[S], back_inserter(available_merchandise));
    }

    // 足りなければ 0 円の商品を足しておく
    if (available_merchandise.size() < K) {
        available_merchandise.resize(K);
    }
    // 大きいほうから K 個を求め
    ranges::nth_element(available_merchandise, available_merchandise.begin() + K, greater{});
    // 合計を出力
    cout << ranges::fold_left(available_merchandise | views::take(K), 0ul, plus{}) << endl;
    return 0;
}
N, M, K, Q = map(int, input().split())

# それぞれの区画にある商品の販売価格
merchandise = [[] for i in range(M)]
for i in range(N):
    V, C = map(int, input().split())
    C -= 1
    merchandise[C].append(V)

# 並べられる商品の販売価格の一覧
available_merchandise = []
for S in map(int, input().split()):
    S -= 1
    available_merchandise += merchandise[S]

# 大きいほうから商品を並べ
available_merchandise.sort(reverse=True)
print(sum(available_merchandise[:min(K, len(available_merchandise))]))

投稿日時:
最終更新: