伝説の始まり
問題概要
個の整数 が与えられる。
これらを 個ずつ 組作り、各組についての「小さい方の値」の総和を最大にしたい。
制約
考えたこと
小さすぎる値と大きすぎる値とを組合せてしまうと、大きい値が小さい値に吸収されてしまって損をする。
例えば、(3, 5, 98, 100) のとき、
- (3 と 100)
- (5 と 98)
みたいにしてしまうと、98 も 100 も消えて 3 + 5 = 8 となって大損である。このようなことを防ぐためには、小さいものは小さいもの同士、大きいものは大きいもの同士組んだ方がいい。
具体的には 個の整数全体を小さい順にソートして ( とする)、その順に 2 つ組を作って行くのが良い。
念のための証明 (本番はここまでしなくて良さそう)
厳密に証明しようと思ったら、「その答えより小さくは絶対にできない」ことを言えば良くて、一般に
- 番目の組のスコアが より小さくはできない
ということが言えるので、全体として
より小さくすることはできない。しかるにこれは「小さい順に 2 つ組を作る」という方法で達成できるので、これが最適解である。
#include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { int N; cin >> N; vector<int> L(N*2); for (int i = 0; i < N*2; ++i) cin >> L[i]; sort(L.begin(), L.end()); int res = 0; for (int i = 0; i < N*2; i += 2) res += L[i]; cout << res << endl; }