P2949 【USACO09OPEN】 Work Scheduling G

P2949 [USACO09OPEN] Work Scheduling G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

反悔贪心

记录详情 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>

#define x first
#define y second

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 100010;

int n, m;
PII g[N];
priority_queue<PII, vector<PII>, greater<PII>> q;


int main()
{
    cin >> n;
    for (int i = 1; i <= n; i ++ )
    {
        int l, r;
        scanf("%d%d", &l, &r);
        g[i] = {l, r};
    }
    
    sort(g + 1, g + 1 + n);
    
    LL ans = 0;
    for (int i = 1; i <= n; i ++ )
    {
        swap(g[i].x, g[i].y);
        if (g[i].y > q.size()) 
        {
            q.push(g[i]);
            ans += g[i].x;
        }
        else
        {
            auto t = q.top();
            if (t.x >= g[i].x) continue;
            q.pop();
            q.push(g[i]);
            ans -= t.x;
            ans += g[i].x;
        }
    }
    cout << ans << endl;
    
    return 0;
}

线段树上二分

记录详情 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>

#define x first
#define y second

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 200010;

int n, m;
PII g[N];
int trs[N];
bool st[N];

struct Node 
{
    int l, r;
    int sum;
}tr[N * 4];

void pushup(Node &u, Node &l, Node &r)
{
    u = {l.l, r.r, l.sum + r.sum};
}

void pushup(int u)
{
    pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}

void build(int u, int l, int r)
{
    if (l == r) tr[u] = {l, r, 0};
    else
    {
        tr[u] = {l, r};
        int mid = l + r >> 1;
        build(u << 1, l, mid);
        build(u << 1 | 1, mid + 1, r);
        pushup(u);
    }
}

void modify(int u, int x, int k)
{
    if (tr[u].l == tr[u].r) tr[u].sum = k;
    else 
    {
        int mid = tr[u].l + tr[u].r >> 1;
        if (x <= mid) modify(u << 1, x, k);
        else modify(u << 1 | 1, x, k);
        pushup(u);
    }
}


int query(int u, int l, int r)
{
    if (tr[u].l == tr[u].r) 
    {
        if (tr[u].sum) return -1;
        return tr[u].l;
    }
    else if (l <= tr[u].l && tr[u].r <= r)
    {
        int ls = tr[u << 1 | 1].l, rs = tr[u << 1 | 1].r, len = rs - ls + 1; 
        if (tr[u << 1 | 1].sum < len) return query(u << 1 | 1, l, r);
        else return query(u << 1, l, r);
    }
    else 
    {
        int mid = tr[u].l + tr[u].r >> 1;
        int res = -1;
        if (r > mid) res = query(u << 1 | 1, l, r);
        if (res == -1 && l <= mid) res = query(u << 1, l, r);
        return res;
    }
}

int query1(int u, int l, int r)
{
    if (l <= tr[u].l && tr[u].r <= r) return tr[u].sum;
    else 
    {
        int mid = tr[u].l + tr[u].r >> 1, sum = 0;
        if (r > mid) sum += query1(u << 1 | 1, l, r);
        if (l <= mid) sum += query1(u << 1, l, r);
        return sum;
    }
}

int main()
{
    cin >> n;
    int maxv = 0;
    for (int i = 1; i <= n; i ++ )
    {
        int a, b;
        scanf("%d%d", &a, &b);
        a = min(a, 100010);
        g[i] = {b, a};
        maxv = max(a, maxv);
    }
    
    sort(g + 1, g + 1 + n);
    reverse(g + 1, g + 1 + n);
    
    build(1, 1, maxv);
    
    LL sum = 0;
    for (int i = 1; i <= n; i ++ )
    {
        int x = query(1, 1, g[i].y);
        // cout << x << endl;
        if (x != -1) 
        {
            modify(1, x, 1);
            // cout << x << endl;
            sum += g[i].x;
        }
    }
    cout << sum << endl;
    return 0;
    
}

树状数组 + 二分

记录详情 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>

#define x first
#define y second

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int N = 100010;

int n, m;
PII g[N];
int trs[N];

struct Node 
{
    int l, r;
    int sum;
}tr[N * 4];

bool cmp(PII a, PII b)
{
    return a.x > b.x;    
}

void pushup(Node &u, Node &l, Node &r)
{
    u = {l.l, r.r, l.sum + r.sum};
}

void pushup(int u)
{
    pushup(tr[u], tr[u << 1], tr[u << 1 | 1]);
}

void build(int u, int l, int r)
{
    if (l == r) tr[u] = {l, r, 0};
    else
    {
        tr[u] = {l, r};
        int mid = l + r >> 1;
        build(u << 1, l, mid);
        build(u << 1 | 1, mid + 1, r);
        pushup(u);
    }
}

void modify(int u, int x, int k)
{
    if (tr[u].l == x && tr[u].r == x) tr[u].sum = k;
    else 
    {
        int mid = tr[u].l + tr[u].r >> 1;
        if (x <= mid) modify(u << 1, x, k);
        else modify(u << 1 | 1, x, k);
        pushup(u);
    }
}


int query(int u, int l, int r)
{
    if (l <= tr[u].l && tr[u].r <= r) return tr[u].sum;
    else
    {
        int mid = tr[u].l + tr[u].r >> 1, sum = 0;
        if (l <= mid) sum += query(u << 1, l, r);
        if (r > mid) sum += query(u << 1 | 1, l, r);
        return sum;
    }
}

int find(int x)
{
    int l = 0, r = x;
    
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        
        if (query(1, max(1, mid), x) < x - mid + 1) l = mid;
        else r = mid - 1;
    }
    return l;
}

int main()
{
    cin >> n;
    int maxv = 0;
    for (int i = 1; i <= n; i ++ )
    {
        int a, b;
        scanf("%d%d", &a, &b);
        a = min(a, (int)1e5);
        g[i] = {b, a};
        maxv = max(a, maxv);
    }
    
    sort(g + 1, g + 1 + n, cmp);
    build(1, 1, maxv);
    
    LL sum = 0;
    for (int i = 1; i <= n; i ++ )
    {
        int x = find(g[i].y);
        if (x) 
        {
            modify(1, x, 1);
            sum += g[i].x;
        }
    }
    
    
    
    cout << sum << endl;
    return 0;
    
}
posted @ 2024-11-10 22:13  blind5883  阅读(1)  评论(0编辑  收藏  举报