AOJ 1297 Swimming Jam

問題

2レーンのプールでn人の人が泳ぐ。
それぞれのレーンは往路、復路の一方通行であり、レーンの幅は狭いため、
途中で泳いでる人を抜かすことはできない。


i番目の人は、レーンを片道泳ぐのにt[i]の時間がかかる。c[i]往復泳ぐとプールから出る。


前に、自分より遅い人が泳いでいてぶつかると、その人は前の人のペースに合わせて泳ぐ。
レーンの端にきてターンするときに、速い人は遅い人を抜かす。
3人以上が詰まっている場合も、同様にターンのときに抜かすことができる。


全員が泳ぎ終わるまでにかかる時間はいくらか、求めよ。

制約条件

n≦50

方針

キューを二つ使ってシミュレーションする。
今のレーンの端まで来る時間をキューに入れて、取り出していく。


前の遅い人にぶつかるというのは、キューに5, 3, 3, 3のように入っているときで、
キューの先頭以下の時間を全部一気に取り出して、
速い順に次のキューに入れれば衝突のあと抜かすというのをきちんと処理できる。


最初に、速い順にキューに入れなければならないことに注意する。

ソースコード

int n, c[50], t[50];
bool cmp(const pi &a, const pi &b){
	return t[a.F] < t[b.F];
}
int main(){
	while(cin >> n, n){
		rep(i, n) cin >> t[i] >> c[i];
		vector<pi> vv;
		rep(i, n) vv.pb(mp(t[i], i));
		sort(all(vv));
		queue<pair<int, pi> > q[2];
		rep(i, n) q[0].push(mp(vv[i].S, mp(vv[i].F, 0)));
		
		int cur = 0, next = 1, ans = 0;
		while(q[0].size() || q[1].size()){
			
			if(q[cur].empty()) swap(cur, next);
			else if(q[next].size() && q[cur].front().S.F > q[next].front().S.F) swap(cur, next);
			
			vector<pi> v;
			int nxt = q[cur].front().S.F;
			while(q[cur].size() && q[cur].front().S.F <= nxt){
				v.pb(mp(q[cur].front().F, q[cur].front().S.S));
				q[cur].pop();
			}
			sort(all(v), cmp);
			rep(i, v.size()){
				if(cur == 1) v[i].S++;
				if(v[i].S == c[v[i].F]) assert(ans <= nxt), ans = nxt;
				else q[next].push(mp(v[i].F, mp(nxt + t[v[i].F], v[i].S)));
			}
		}
		cout << ans << endl;
	}
	return 0;
}int n, c[50], t[50];
bool cmp(const pi &a, const pi &b){
	return t[a.F] < t[b.F];
}
int main(){
	while(cin >> n, n){
		rep(i, n) cin >> t[i] >> c[i];
		vector<pi> vv;
		rep(i, n) vv.pb(mp(t[i], i));
		sort(all(vv));
		queue<pair<int, pi> > q[2];
		rep(i, n) q[0].push(mp(vv[i].S, mp(vv[i].F, 0)));
		
		int cur = 0, next = 1, ans = 0;
		while(q[0].size() || q[1].size()){
			
			if(q[cur].empty()) swap(cur, next);
			else if(q[next].size() && q[cur].front().S.F > q[next].front().S.F) swap(cur, next);
			
			vector<pi> v;
			int nxt = q[cur].front().S.F;
			while(q[cur].size() && q[cur].front().S.F <= nxt){
				v.pb(mp(q[cur].front().F, q[cur].front().S.S));
				q[cur].pop();
			}
			sort(all(v), cmp);
			rep(i, v.size()){
				if(cur == 1) v[i].S++;
				if(v[i].S == c[v[i].F]) assert(ans <= nxt), ans = nxt;
				else q[next].push(mp(v[i].F, mp(nxt + t[v[i].F], v[i].S)));
			}
		}
		cout << ans << endl;
	}
	return 0;
}