
配点: 300 点 / 実行時間制限: 2 sec / メモリ制限: 1024 MB / Difficulty: 223 / NoviSteps: 3Q
問題概要
番号が付けられた 個の城壁と
個の砲台があり、砲台
は
以上
以下の番号の城壁を守っている。
ある砲台を破壊すると、その砲台が守っていた城壁はその砲台により守られなくなる。どの砲台にも守られていない城壁が存在する状態にするためには、最小で何個の砲台を破壊する必要があるか求めよ。
制約
- 入力はすべて整数
考察
各城壁が何個の砲台によって守られているのかを記録しておけば、その和の最小値を取ることによって、破壊すべき砲台の個数を求めることができる。
具体的には、下図の のような配列の最小値を求めればよい。
さて、上に示したようなテーブルを作っていく過程において、各砲台の守備範囲 について1マスずつフラグを立てていくのでは計算量が
となって TLE してしまう。
そこで、imos法を用いてこの処理を効率化しよう。
詳細な実装は実装例を参照してほしい。これで計算量は に落とすことができた。
実装例
#include <bits/stdc++.h> using namespace std; #define rep(i, start, end) for (auto i = (start); (i) < (end); (i)++) constexpr int INF = 1e+9; template <typename T> inline bool chmin(T &a, T b) { return ((a > b) ? (a = b, true) : (false)); } // ======================================== // int main() { int N, M; cin >> N >> M; vector<int> c(N + 2, 0); rep(i, 0, M) { int L, R; cin >> L >> R; c[L]++; c[R + 1]--; } rep(i, 1, N + 1) c[i] += c[i - 1]; int ans = INF; rep(i, 1, N + 1) { chmin(ans, c[i]); } cout << ans << endl; return 0; }
実装時間: 5分
コメント
C問題は久しぶりに素直な感じになった。いつもこれぐらいだと安心できるのだが...