- 長さNで全部0の配列に対して(1)どれかに1を足す,(2)全部を2倍する, を繰り返して別途与えられる長さNの配列Dと等しくしたい。最小手数を求める。
- 1≦N≦50, 0≦D[i]≦1000
- できるかぎり2倍は使った方が良いだろう(証明なし)
- ビット表現で1になってるとこは必ず1を足す操作で作られるはず。タイミングは2倍2倍に増えてく途中でここぞというときにやればいい
- なので一番大きな数に対して2倍を適用する回数 + 全ての数のbit countが答え
class IncrementAndDoubling {
public:
int getMin(vector <int> D) {
int ans = 0;
REP(i, D.size()) ans += POPCOUNT(D[i]);
int mx = 0;
REP(i, D.size()) mx=max(mx, D[i]);
while(mx>1) { ans++;mx>>=1;}
return ans;
}
};