いつもより簡単目なDiv2かと思ったら、CもEもしょうもないミスで落とした。
http://codeforces.com/contest/551/problem/C
問題
M人でN個の箱の山を片付けたい。
N個の山は1列に並んでおり、左からi個目の山にはA[i]個積まれている。
M人は左端の山のさらに左にいる。
時間1当たり、各人は一つ右の山に移動するか、目の前の山の箱を1個取り除ける。
最短でどれだけの時間ですべての箱を取り除けるか。
解法
二分探索で求めていく。
各人は一番右にある箱が残された山に移動し、その過程で残された時間右側から順に箱を取り除いていけば良い。
1個も箱がない山もあるので、コーナーケースに注意。
int N,M; ll A[101010]; ll B[101010]; bool ok(ll V) { int i; memmove(B,A,sizeof(B)); int cur=N-1; FOR(i,M) { ll v=V; while(cur>=0 && B[cur]==0) cur--; if(cur<0) return true; v-=(cur+1); if(v<0) return false; while(cur>=0 && v>0) { if(B[cur]>v) { B[cur]-=v; break; } v-=B[cur--]; } } while(cur>=0 && B[cur]==0) cur--; return cur<0; } void solve() { int i,j,k,l,r,x,y; string s; cin>>N>>M; FOR(i,N) cin>>A[i]; ll ret=(1LL<<60)-1; for(i=59;i>=0;i--) if(ok(ret-(1LL<<i))) ret -= 1LL<<i; cout<<ret<<endl; }
まとめ
1個も箱がない山の処理をミスってWAした。