看直播 csust oj

看直播

Description

 

小明喜欢看直播,他订阅了很多主播,主播们有固定的直播时间 [Li, Ri] 。

可是他网速只有2M,不能同时播放两个直播,所以同一时间只能看一个直播。

并且他只会去看能完整看完的直播(从开播到停播都能观看)。

他想知道最多能看多长时间的直播呢?

注意 [1, 3] 和 [3, 4] 不能两者都选择。

Input

 

第一行一个N。

接下来N行每行两个整数Li, Ri。

1 <= N <= 2e5

1 <= Li <= Ri <= 1e9

Output

 

输出最多能看的时间。

Sample Input 1 

3
1 3
2 6
5 8

Sample Output 1

 

  7

 

这个题目不是特别难,可以用很多方法写。

 

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <queue>
#include <vector>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 4e5 + 10;
struct node
{
    ll l, r, com;
    node(ll l=0,ll r=0,ll com=0):l(l),r(r),com(com){}
}ex[maxn];
ll dp[maxn], a[maxn];
struct edge
{
    int ed, w;
    edge(int ed=0,int w=0):ed(ed),w(w){}
};
vector<edge>e[maxn];

int main()
{
    int n, tot = 0;
    scanf("%d", &n);
    for(int i=1;i<=n;i++)
    {
        int l, r;
        scanf("%d%d", &l, &r);
        ex[i] = node(l, r, 0);
        a[++tot] = l;
        a[++tot] = r;
    }
    sort(a + 1, a + 1 + tot);
    int len = unique(a + 1, a + 1 + tot) - a - 1;
    for(int i=1;i<=n;i++)
    {
        ex[i].com = ex[i].r - ex[i].l + 1;
        ex[i].l = lower_bound(a + 1, a + 1 + len, ex[i].l) - a;
        ex[i].r = lower_bound(a + 1, a + 1 + len, ex[i].r) - a;
        e[ex[i].l].push_back(edge(ex[i].r,ex[i].com));
    }
    for(int i=len;i>=1;i--)
    {
        dp[i] = dp[i + 1];
        for(int j=0;j<e[i].size();j++)
        {
            edge x = e[i][j];
            dp[i] = max(dp[i], dp[x.ed + 1] + x.w);
        }
    }
    printf("%lld\n", dp[1]);
    return 0;
}
纯dp
Dragon plus 14:50:56
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define fir first
#define sec second
using namespace std;

typedef pair<int,int> P;

const int maxn = 2e5+7;

int n,len;
P s[maxn];
int v[maxn<<2];
int Max[maxn<<4];

bool cmp(const P& a,const P& b) {
    return a.sec<b.sec;
}

void pushup(int num) {Max[num] = max(Max[num<<1],Max[num<<1|1]);}

void build(int l,int r,int num) {
    if(l==r) {
        Max[num]=0;
        return ;
    }
    int mid = (l+r) >>1;
    build(l,mid,num<<1);
    build(mid+1,r,num<<1|1);
    pushup(num);
}

void modify(int l,int r,int num,int pos,int mods) {
    if(pos<l || r <pos) return ;
    if(pos<=l&&r<=pos) {
        Max[num] = max(Max[num],mods);
        return ;
    }
    int mid = (l+r) >>1;
    if(pos<=mid) modify(l,mid,num<<1,pos,mods);
    if(mid< pos) modify(mid+1,r,num<<1|1,pos,mods);
    pushup(num);
}

int quriy(int l,int r,int num,int le,int ri) {
    if(ri<l || r<le) return 0;
    if(le<=l && r<=ri) return Max[num];
    int mid = (l+r) >>1;
    int ans = 0;
    if(le<=mid) ans = max(ans,quriy(l,mid,num<<1,le,ri));
    if(mid< ri) ans = max(ans,quriy(mid+1,r,num<<1|1,le,ri));
    return ans;
}

int main() {
    int now =1;
    scanf("%d",&n);
    for(int i=0;i<n;i++) {
        scanf("%d%d",&s[i].fir,&s[i].sec);
        v[now++] = s[i].fir;
        v[now++] = s[i].sec;
    }
    sort(v,v+now);
    sort(s,s+n,cmp);
    len = unique(v,v+now)-v;
    build(1,len,1);
    for(int i=0;i<n;i++) {
        int res = s[i].sec -s[i].fir+1;
        int d = lower_bound(v,v+len,s[i].fir)-v;
        int d2 = lower_bound(v,v+len,s[i].sec)-v+1;
        res += quriy(1,len,1,1,d);
        modify(1,len,1,d2,res);
    }
    printf("%d\n",quriy(1,len,1,1,len));
    return 0;
}
dp+线段树
#include <iostream>
#include <algorithm>
#include <cstdio>
#define fir first
#define sec second
using namespace std;

typedef pair<int,int> P;

const int maxn = 2e5+7;

bool cmp(const P&a,const P&b) {
    return a.sec<b.sec;
}

int n,lst;
P s[maxn];
int dp[maxn<<2];
int v[maxn<<2];
int p[maxn];

int main() {
    int now = 1;
    scanf("%d",&n);
    for(int i=0;i<n;i++) {
        scanf("%d%d",&s[i].fir,&s[i].sec);
        v[now++]=s[i].fir;
        v[now++]=s[i].sec;
    }
    int ans = 0;
    sort(v,v+now);
    sort(s,s+n,cmp);
    int len = unique(v,v+now)-v;
    for(int i=0;i<n;i++) {
        int d = s[i].sec - s[i].fir+1;
        int l = lower_bound(v,v+len,s[i].fir)-v;
        int r = lower_bound(v,v+len,s[i].sec)-v;
        int Max = lower_bound(p,p+lst+1,l)-p-1;
        //cout<<p[Max]<<' '<<dp[p[Max]]<<endl;
        dp[r] = max(dp[r],dp[p[Max]]+d);
        ans = max(dp[r],ans);
        //cout<<r<<' '<<dp[r]<<' '<<lst<<endl;
        if(dp[p[lst]] >= dp[r]) continue;
        else {
            if(p[lst] != r) p[++lst] = r; 
        }
    }
    printf("%d\n",ans );
    return 0;
}
CSUST Online Judge

Powered by OnlineJudge   Version: 20190727-ed4d6
dp+单调队列
#include <bits/stdc++.h>
using namespace std;
const int MAX = 2e5 + 50;

struct date {
    int le, ri;
} a[MAX];
int lsh[MAX * 2];

bool cmp(date A, date B) {
    if (A.le != B.le) {
        return A.le < B.le;
    }
    else {
        return A.ri < B.ri;
    }
}

int dp[MAX * 2];
int s[MAX * 2];
int main() {
    int n;
    scanf("%d", &n);
    int cnt = 0;
    for (int i = 1; i <= n; i++) {
        scanf("%d%d", &a[i].le, &a[i].ri);
        lsh[++cnt] = a[i].le;
        lsh[++cnt] = a[i].ri;
    }

    sort(lsh + 1, lsh + cnt + 1);
    cnt = unique(lsh + 1, lsh + cnt + 1) - lsh - 1;

    sort(a + 1, a + n + 1, cmp);

    for (int i = 1; i <= n; i++) {
        a[i].le = lower_bound(lsh + 1, lsh + cnt + 1, a[i].le) - lsh;
        a[i].ri = lower_bound(lsh + 1, lsh + cnt + 1, a[i].ri) - lsh;
    }

    int k = 1;
    int top = 1, tail = 0;
    for (int i = 1; i <= cnt && k <= n; i++) {
        while (i == a[k].le) {
            dp[a[k].ri] = max(dp[a[k].ri], lsh[a[k].ri] - lsh[a[k].le] + s[top] + 1);
            k++;
        }
        while (top <= tail && s[tail] <= dp[i]) {
            tail--;
        }
        s[++tail] = dp[i];
    }
    int ans = 0;
    for (int i = 1; i <= cnt; i++) {
        ans = max(ans, dp[i]);
    }
    printf("%d\n", ans);
    return 0;
}
dp+单调队列




猜你喜欢

转载自www.cnblogs.com/EchoZQN/p/11273049.html
OJ
今日推荐