SRM 204 DIV1 Hard WorldPeace
問題
数列countriesと数値kが与えられる。
[0,|countries|)の中から重複なしでkつ選んだものの数を最大化せよ。
ただし、iはcountries[i]個までしか使えない。
- 2<=k<=20
- k<=|countries|<=50
- 1<=countries[i]<=10^9
解答
Editorialを読んだ。
単純に作る数を二分探索すればよい。
判定は(Sum {min(m, countries[i])} >= m*k)という単純なもの
コメント
非常に簡単な解答。しかし思いつけなかった。
考えたのはgreedyを高速化する方法で、これはEditorialでも「駄目な複雑な考え方」としてたくさんの人がそうしていたと書いてあった。
まず、二分探索が考える段階で一度も考えてないことが駄目だ。二分探索は常に考えよう
コード
#include <string> #include <vector> #include <algorithm> #include <numeric> #include <set> #include <map> #include <queue> #include <iostream> #include <sstream> #include <cstdio> #include <cmath> #include <ctime> #include <cstring> #include <cctype> #define rep(i,n) for(int (i)=0;(i)<(int)(n);++(i)) using namespace std; typedef long long ll; struct WorldPeace { long long numGroups(int k, vector <int> c) { ll l = 0, u = 100000000000LL; while(u-l > 1) { ll m = (l+u) / 2; ll x = 0; rep(i, c.size()) { if(c[i] > m) x += m; else x += c[i]; } if(x >= k * m) l = m; else u = m; } return l; } };