ABC461C - Variety

解法

基本的には貪欲に価値が高いものを選んでいけばよい。
ただし、色を最低でも $M$ 種類選ばなければいけない点に工夫が必要となる。

まず、手作業か何かでやるなら、以下のように考えることができる。
まず、各色の中で最も価値が高いものだけ見ていき、価値が高いものから $M$ 個を採用する。
その後、まだ採用していないものだけ見ていき、価値が高いものから $K-M$ 個を採用する。
しかし、プログラムで書くと若干面倒であるため、これを少し改良する。

後半で考える $K-M$ 回を、「一度採用した色との重複が許される上限回数」と読み替える。
すると、全ての宝石を価値の高い順に見て、以下の処理をすればよい。

採用した宝石が $K$ 個になった時点で打ち切って、採用した価値の合計を答えればよい。

入力例1での動作

入力を受け取る。
$C$ と $V$ は、価値 $V$ を前に出して、降順の priority_queue に入れておく。

n: 5
k: 3
m: 2
pq: {(50,1) | (30,1), (40,1), (10,2), (20,3)}

選んだことがある色の set を持っておく。
色の重複が何回まであっても許されるかを $3-2 = 1$ と求める。
採用した個数のカウンターも持っておく。

color_set: {}
allowed: 1
counter: 0

最も価値の高い宝石 (50,1) を取り出す。
新しい色なので、採用して color_set を更新。

pq: {(40,1) | (30,1), (10,2), (20,3)}
color_set: {1}
allowed: 1
counter: 1
result: 50

最も価値の高い宝石 (40,1) を取り出す。
既存色だが allowed が残っているので、採用して allowed を更新。

pq: {(30,1) | (10,2), (20,3)}
color_set: {1}
allowed: 0
counter: 2
result: 90

最も価値の高い宝石 (30,1) を取り出す。
既存色かつ allowed が残っていないので、不採用。

pq: {(20,3) | (10,2)}
color_set: {1}
allowed: 0
counter: 2
result: 90

最も価値の高い宝石 (20,3) を取り出す。
新しい色なので、採用して color_set を更新。

pq: {(10,2) | }
color_set: {1, 3}
allowed: 0
counter: 3
result: 110

注意点

宝石の価値をいくつも加算すると、int 型からはみ出る。
結果用変数には long long 型を用いること。

別解

特になし。