Description
You are painting a fence with n sections, numbered from 1 to n. There are k artists, each willing to paint their design on a specific portion of the fence. However, artists will never agree to have their section painted over, so they will only paint their portion of the fence if no one else will paint
any part of it.
You want to select a set of painters that does not conflict to minimize the number of unpainted sections.
Translation
给定一些线段,在范围 [1,n] 内,选择一些线段使得这些线段不相交且总长度最长(输出剩余未覆盖区域最小)。
Input
The first line contains two positive integers
n(1≤n≤1018)
and
k(1≤k≤200,000)
.
Each of the next
k
lines contains two positive integers
Output
Print, on a single line, a single integer indicating the minimum number of unpainted sections.
Sample Input
8 3
1 3
2 6
5 8
Sample Output
1
Solution
看起来像是一道经典的题目?
排序然后贪心?不过下面的程序是DP。
Code
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 200005;
typedef long long ll;
struct Segment {
ll l, r, w;
bool operator< (const Segment &b) const {
return r < b.r;
}
} s[N];
ll f[N][2];
int binary_search(int l, int r, ll x) {
int ans = 0, mid;
while (l <= r) {
mid = l + r >> 1;
if (s[mid].r < x)
ans = mid, l = mid + 1;
else
r = mid - 1;
}
return ans;
}
int main() {
ll n, painted = 0;
int i, m;
cin >> n >> m;
for (i = 1; i <= m; ++ i) {
cin >> s[i].l >> s[i].r;
s[i].w = s[i].r - s[i].l + 1;
}
sort(s + 1, s + m + 1);
f[1][1] = s[1].w;
for (i = 2; i <= m; ++ i) {
f[i][0] = max(f[i - 1][0], f[i - 1][1]);
int pre = binary_search(1, m, s[i].l);
f[i][1] = max(f[pre][0], f[pre][1]) + s[i].w;
painted = max(painted, max(f[i][0], f[i][1]));
}
cout << n - painted << endl;
return 0;
}