UVALive 7959|Gym 101201H|Paint|DP|贪心

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(1n1018) and k(1k200,000) .
Each of the next k lines contains two positive integers ai and bi , where 1aibin , indicating that the i th artist wants to paint all sections between section ai and section bi, inclusive.

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值