面白い問題!
問題概要
箱 とボール
がある。ボール
は箱
に入っていて、その重さは
である。
これから、ボールの入っている箱を移すことで、どの箱にもちょうど 1 個ずつボールが入っている状態にしたい。ボールを移すコストは、そのボールの重さである。
実現するための最小コストを求めよ。
制約
考えたこと
たとえば、、
、
の場合を考えてみよう。このとき、
- 箱 2 に、重さが
のボール (小さい順)
- 箱 4 に、重さが
のボール
- 箱 5 に、重さが
のボール (小さい順)
という状況になっている。まず、箱 4 については何もする必要がない。箱 2 については、3 個のボールのうち、重さが小さい 2 個のボールを他に移せばよい (移す先の箱はなんでもよい)。箱 5 についても、2 個のボールのうち、重さが小さい 5 のボールを他に移せばよい。
一般に、ボールが複数個ある箱について、重さが最大のものを除外したボールの重さの総和を求め、その箱ごとに総和をとればよい。
計算量は となる。
コード
このコードでは、各箱のボールの重さの最大値を求めるのにソートを用いているので、計算量は となっている。
#include <bits/stdc++.h> using namespace std; int main() { int N; cin >> N; vector<long long> A(N), W(N); for (int i = 0; i < N; ++i) cin >> A[i], --A[i]; for (int i = 0; i < N; ++i) cin >> W[i]; vector<vector<long long>> tot(N); for (int i = 0; i < N; ++i) tot[A[i]].push_back(W[i]); for (int v = 0; v < N; ++v) sort(tot[v].begin(), tot[v].end()); long long res = 0; for (int v = 0; v < N; ++v) { for (int i = 0; i + 1 < tot[v].size(); ++i) res += tot[v][i]; } cout << res << endl; }