Paint题解 DP+二分

版权声明: https://blog.csdn.net/leelitian3/article/details/81809710

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.

Input

The first line contains two positive integers n(1≤n≤1018)n(1≤n≤1018) and k(1≤k≤200,000)k(1≤k≤200,000). 
Each of the next kk lines contains two positive integers aiai and bibi, where 1≤ai≤bi≤n1≤ai≤bi≤n, indicating that the iith artist wants to paint all sections between section ai and section bibi, 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


Translation

题目给定k个在[1,n]范围内的闭区间,求一个不重叠区间的组合,使得覆盖长度最大。输出这个最大长度。

Solution

①按右端点排序,dp[i]保存考虑前i个区间时的最大覆盖长度。
②求dp[i]时二分找到最后一个不与i重叠的区间j,dp[i]=dp[j]+length[i+1]。
原因:按右端点排序,j之前的肯定不会和i重叠。

 

#include <iostream>
#include <cstring> 
#include <algorithm>
using namespace std;

struct Seg
{
    long long low, high;
    friend bool operator < (const Seg a, const Seg& b)	//按右端点排序 
    {
        if(a.high != b.high) return a.high < b.high;
        return a.low < b.low;
    }
};

bool cmp(const Seg& a, const Seg& b)	//不重叠 
{
    return a.high < b.low;
}

Seg seg[200005];
long long dp[200005];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    long long n, k;
    cin >> n >> k;

    memset(seg, 0, sizeof(seg));

    for(int i = 1; i <= k; ++i)
        cin >> seg[i].low >> seg[i].high;
    sort(seg, seg + k + 1);					//seg[0]保存的都是0,简化边界 

    for(int i = 1; i <= k; ++i)
    {
        int j = lower_bound(seg, seg + i, seg[i], cmp) - seg - 1;	//最后一个不重叠区间 
        dp[i] = dp[j] + seg[i].high - seg[i].low + 1;
        if(dp[i] < dp[i - 1]) dp[i] = dp[i - 1];
    }

    cout << n - dp[k];
    return 0;
}

猜你喜欢

转载自blog.csdn.net/leelitian3/article/details/81809710