• POJ


    相交区间选尽量少的点是可以贪心的,右端点排序以后,尽量往右边放可以得到可以使得点在区间尽可能多。

    但是我只想到了O(n)的维护方法。(数据比较水,能过...

    或者是前缀和可以写sum(bi) - sum(ai-1) ≥ ci

    再加上前缀和的单调性 sum(i) - sum(i-1) ≥ 0

    以及一个点只能选一次 sum(i-1) - sum(i) ≥ -1。

    左边具有可加性的,根据对偶性:min ( sum(n) - sum(0) ) ≥ max( c )

    右边就是求一个最长路了。

    复杂度:O(VE)。

    两种复杂度都爆了,还是能过,大力出奇迹。。。

    #include<cstdio>
    #include<iostream>
    #include<string>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<vector>
    #include<map>
    #include<set>
    #include<algorithm>
    #include<cmath>
    #include<numeric>
    using namespace std;
    
    typedef long long ll;
    
    
    const int maxn = 50000+5;
    const int maxm = maxn*3;
    
    int dat[2][maxn];
    int * const d = dat[0]+1;
    
    int * const hd = dat[1]+1;
    int nx[maxm];
    int a[maxn], b[maxm], c[maxm];
    int ec;
    
    void add_edge(int u, int v, int w)
    {
        c[ec] = w;
        b[ec] = v;
        nx[ec] = hd[u];
        hd[u] = ec++;
    }
    
    int n;
    
    int q[maxn];
    bool inq[maxn];
    
    int spfa(int s, int t)
    {
        memset(d+s,0xff,sizeof(int)*(t-s+1));
        int top = 0;
        q[++top] = s; d[s] = 0; inq[s] = true;
        while(top){
            int u = q[top--];
            inq[u] = false;
            for(int i = hd[u]; ~i; i = nx[i]){
                int v = b[i];
                if(d[v] < d[u] + c[i]){
                    d[v] = d[u] + c[i];
                    if(!inq[v]) {
                        q[++top] = v;
                        inq[v] = true;
                    }
                }
            }
        }
        return d[t];
    }
    
    void solve()
    {
        for(int i = 0; i < n; i++){
            scanf("%d%d%d", a+i, b+i, c+i);
        }
        int s = *min_element(a,a+n)-1, t = *max_element(b,b+n);
        memset(hd+s, 0xff, sizeof(int)*(t-s+1));
        for(int i = 0; i < n; i++){
            nx[i] = hd[--a[i]];
            hd[a[i]] = i;
        }
        ec = n;
        for(int i = s; i < t; i++){
            add_edge(i,i+1,0);
            add_edge(i+1,i,-1);
        }
    
        printf("%d
    ", spfa(s,t));
    }
    
    
    //#define LOCAL
    int main()
    {
    #ifdef LOCAL
        freopen("in.txt","r",stdin);
    #endif
        while(~scanf("%d",&n)){
            solve();
        }
        return 0;
    }
  • 相关阅读:
    WebSocket面试题
    面试题、四
    面试题、三
    面试题、二
    面试题、一
    vue 使用localstorage实现面包屑
    flutter,SliverPersistentHeader实现Tab顶部吸附固定效果
    对flutter中,ExpsionPanel的简单改造
    node.js学习笔记
    PHP和Redis实现在高并发下的抢购及秒杀功能示例详解
  • 原文地址:https://www.cnblogs.com/jerryRey/p/5004648.html
Copyright © 2020-2023  润新知