O(n) の貪欲で解ける。
操作は、"Kの倍数を作る"、"全部上の階へ渡す"、"(倍数にならなくても)とにかく上の階から持ってくる"、の3パターンがある。
倍数を作れるなら極力そうした方が良いのは直感的に明らか。
m 階に注目しているとして、m 階に m - 1 階から幾人か上がってきている場合、彼らはその階で消費する必要がある。
その際、上の階からKの倍数にならないとしても全員を持ってきた方が、それより上の階で消費されるべき人数を減らせる。
苦戦した。貪欲は難しいと再認識した。
class TheJediTest {
public:
int minimumSupervisors(vector <int> v, int K)
{
const int N = v.size();
vector<int> u = v;
for (int i = 0; i + 1 < N; ++i) {
int req = (K - (u[i] % K)) % K;
if (req <= v[i + 1]) {
v[i + 1] -= req;
u[i + 1] -= req;
u[i] += req;
} else {
if (v[i] < u[i]) {
u[i] += v[i + 1];
v[i + 1] = 0;
u[i + 1] = 0;
} else {
u[i + 1] += v[i];
u[i] -= v[i];
v[i] = 0;
}
}
}
int sum = 0;
for (int i = 0; i < N; ++i) {
sum += (u[i] / K) + (bool)(u[i] % K);
}
return sum;
}
};