AcWing 362. 區間
阿新 • • 發佈:2022-03-26
思路:
\(s[i]\) 表示前 \(i\) (包括\(i\)) 的數中 選擇了幾個數
所以 \(s[i] >= s[i - 1]\)
題目輸入的 \(a ,b, c\);
\(s[b] - s[a - 1] >= c\);
利用這兩個條件進行差分約束 然後 偏移量為\(1\)空出 \(a[0]\)為偏移點, 就 可以直接得到 dist[50001] 為最終答案。
#include <bits/stdc++.h> using namespace std; //這裡也可以把[a,b]區間往右移動一個單位, //這樣就可以空出來S[0]這個點,作為超級原點 const int N = 50010, M = 150010; int n; int dist[N]; bool st[N]; //鄰接表 int e[M], h[N], idx, w[M], ne[M]; void add(int a, int b, int c) { e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; } void spfa() { queue<int> q; memset(dist, -0x3f, sizeof dist); dist[0] = 0; st[0] = true; q.push(0); while (q.size()) { int t = q.front(); q.pop(); st[t] = false; for (int i = h[t]; ~i; i = ne[i]) { int j = e[i]; if (dist[j] < dist[t] + w[i]) { dist[j] = dist[t] + w[i]; if (!st[j]) { q.push(j); st[j] = true; } } } } } int main() { cin >> n; memset(h, -1, sizeof h); for (int i = 1; i < N; i++) add(i - 1, i, 0), add(i, i - 1, -1); for (int i = 0; i < n; i++) { int a, b, c; cin >> a >> b >> c; a++, b++; //區間往後移動一位 add(a - 1, b, c); } spfa(); printf("%d\n", dist[50001]); return 0; }