Codeforces Beta Round #38

おはようございます、昨日の話です。

この前のJAPLJ contestが3ヶ月ぶりのコンテストでコーディング速度が非常に遅くなっていたので、またリハビリしないとなあと思いながら、SRMなんかも時間が合わなくて中々出れなかった中21:00という久しぶりに参加しやすい時間帯だったので参加したら4時間という長時間で非常に疲れました。因みに今回でyellow(Captain)になりました(・∀・)!

Aは極単純,Bは面倒なだけ,Cはリーディングハード,Dもややリーディングハード,Eは普通,F,Gは読んでません。アルゴリズムの難易度についてはとやかく言える身分じゃないので言及しません。

Eの解法について何人もに訊かれたので、書き留めておきます。

Problem E “Let’s Go Rolling!”

http://codeforces.com/contest/38/problem/E

1 \le n \le 3000 \, , \, -10^9 \le x_{1..n},c_{1..n}\le 10^9
直線上にn個のビー玉(質点)をx[i]置いて左(負方向)に転がします。ビー玉はピンで留める事もできて、転がっててきたビー玉もそこで止まります。各ビー玉のコストc[i]は転がった距離またはピン留めコストです。コストの総和を最小化して下さい。

DPです。右方向にビー玉を追加していきます。今n-1個のビー玉があって、n番目のビー玉を一番右に追加したとします。その時増加するコストは、次のようになります。

  • ピン留めする→そのビー玉のピン留めコスト分
  • ピン留めしない→(一番右の)最後にピン留めした位置までの距離

つまり、n-1個までの情報の内、解を求める為に必要な情報は、n-1個の中で最後にピン留めした位置とそのコストです。最後にピン留めした位置が同じならそれ以降の最適解は同じなので、ピン留めした位置毎に最適(最小)な値を残せばいいことになります。
よって、DPテーブルは次のようになります。下方向にビー玉の数n。右方向に最後にピン留めしたビー玉の番号。括弧書きは(x,c)。データは総コスト(解)。青い矢印はピン留めしないときの解。緑の丸はその行の最適解(最小値)。赤い矢印はピン留めしたときの解。最終的な解は最後の行の最小値です。

DPテーブル
DPテーブル

最後にC++のコードです。図の二次元の表で、新しい行を計算するときには直前の一行の値しか参照していないので、一次元配列を更新していくように実装しています。計算量は変わりません。

#include <iostream>
#include <vector>
#include <algorithm>
#define REP(i,n) for(int i = 0; i < (n); ++i)
#define FOR(i,a,b) for(int i = (a); i < (b); ++i)
#define ALL(cont) (cont).begin(), (cont).end()
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef vector<pii> vii;

int main() {
	int n;
	cin >> n;
	vii x(n);
	REP(i,n) cin >> x[i].first >> x[i].second;
	sort(ALL(x));
	vl c(1, x[0].second);
	FOR(i,1,n) {
		c.push_back(x[i].second + *min_element(ALL(c)));
		REP(j,i) c[j] += x[i].first - x[j].first;
	}
	cout << *min_element(ALL(c)) << endl;

	return 0;
}

インターンとWebSocketの話

夏休みを丸ごと潰してG社で8週間のサマーインターンシップに行ってきました。

HTML5にはあまり詳しくありませんが、WebSocketというまだdraftの新仕様があり、この6月頃から協議が白熱しているそうで、その仕様策定に関わるexperimentsを目標として、platformの実装を行ないました。インターン中に新しいdraftが2回もリリースされて大変でした。現在の最新版はhybi-02です。

WebSocketはWebアプリケーションに新たな通信フレームを与えます。HTTP上に張られる双方向非同期データグラム通信で、オーバーヘッドとレイテンシが非常に少なくなります。例えば、キータイプやマウスイベントを即時サーバーで処理させる等、アプリケーションをディープにクラウド化しても帯域負荷がさほど肥大化しません。興味があればwebsockets.orgに(少し情報は古いですが)分り易い説明とサンプルがあるので動かしてみてください。

WebSocketのAPIを提供するインフラの実装をしていたので、今度は機会があればアプリケーションを作ってみたいです。