0530 Darts (ダーツ)
http://rose.u-aizu.ac.jp/onlinejudge/ProblemSet/description.jsp?id=0529
N 個の得点が与えられ,この中から4つまで選んでその合計を最大値を求める問題.
ただし,合計が M を超えてしまった場合は 0 点になってしまう.
最初 DP でいけるかと思ったけど,サンプルは通ったものの WA だった.
投げられるダーツの矢は4本と限られているので,まず 2 本投げたときにとりうる得点を列挙しこれを v とし,
各 v の要素において,合計が M を超えない v の要素を二分探索で求めてそれの最大値を答えとするコードを書いた.
4本投げない場合もあるので,v に 0 と各得点そのものも入れる必要があることに注意.
N <= 1000 で O(N^2 log N) なので間に合う.
#include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { int N, M; while (cin >> N >> M && N != 0) { vector<int> ps(N); for (int i = 0; i < N; i++) { cin >> ps[i]; } vector<int> v(1, 0); for (int i = 0; i < N; i++) { v.push_back(ps[i]); for (int j = i; j < N; j++) { if (ps[i] + ps[j] <= M) { v.push_back(ps[i] + ps[j]); } } } sort(v.begin(), v.end()); int ans = 0; for (vector<int>::const_iterator it(v.begin()); it != v.end(); ++it) { vector<int>::const_iterator jt = lower_bound(v.begin(), v.end(), M - *it); if (jt != v.begin()) { --jt; ans = max(ans, *it + *jt); } } cout << ans << endl; } return 0; }