WUPC2nd H - ダイヤグラム
問題
日本語なので本文参照(http://wupc2nd.contest.atcoder.jp/tasks/wupc_08)
制約条件
駅の数≦100000
電車の台数≦200
方針
実質的に考える必要がある駅は電車の両端の駅だけなので、最大でも400個。
なので座標圧縮する。
ひとつの電車でのみカバーされている駅の右端をx
二つ以上の電車でカバーされている駅の右端をyとしたとき、(y≦x)
dp[y][x]:=その区間がカバーされている場合の数
を更新していくようなdpをすれば、O(n^3)で答えが求まる。
dpの更新順序に気をつける必要がある。
(同じ電車を二度使わないように、電車→区間1(右から)→区間2(左から)の順でループをまわす)
ソースコード
const int mod = (int)1e9 + 7; int n, m; pi in[200]; ll dp[410][410]; int main(){ cin >> n >> m; vi vs; vs.pb(1); vs.pb(n + 1); rep(i, m){ cin >> in[i].first >> in[i].second; vs.pb(in[i].first); vs.pb(in[i].second + 1); } sort(in, in + m); sort(all(vs)); vs.erase(unique(all(vs)), vs.end()); rep(i, m){ in[i].first = lower_bound(all(vs), in[i].first) - vs.begin(); in[i].second = lower_bound(all(vs), in[i].second + 1) - vs.begin(); } dp[0][0] = 1; rep(i, m) for(int p1 = vs.size() - 1; p1 >= 0; p1--) for(int p2 = p1; p2 >= 0; p2--) if(dp[p1][p2]){ if(in[i].first > p2) continue; int np2 = max(p2, min(p1, in[i].second)); int np1 = max(p1, in[i].second); (dp[np1][np2] += dp[p1][p2]) %= mod; } cout << dp[vs.size() - 1][vs.size() - 1] << endl; return 0; }