[USACO09OPEN]Work Scheduling G

该博客介绍了如何利用树状数组和二分查找解决一个任务安排问题。当截止日期前的任务数量小于截止日期时,所有任务都能完成。如果任务数超过截止日期,采用贪心策略按权重从大到小分配,直到无法再插入。代码示例展示了如何实现这一算法,以确定最大能完成的任务权重总和。
摘要由CSDN通过智能技术生成

算法分析

树状数组上二分

只要截至日期前的任务数量小于截至日期那么就全都可以做完

截止日期前的任务数大于截止日期时,就按照贪心(权重大的)尽可能往后放着,直至塞不进就行

那么就是二分在某个截至日期能塞的最后的位置就可以了

AC Code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
int n,tr[N];
struct node
{
    int t,w;
}a[N];
bool cmp(node a,node b)
{
    return a.w > b.w;
}

int lowbit(int x)
{
    return x & -x;
}

void update(int pos,int v)
{
    while(pos <= n)
    {
        tr[pos] += v;
        pos += lowbit(pos);
    }
}

ll query(int pos)
{
    ll res = 0;
    while(pos)
    {
        res += tr[pos];
        pos -= lowbit(pos);
    }
    return res;
}

int main()
{
    cin >> n;
    for(int i = 1;i <= n;i ++)
    {
        scanf("%d%d",&a[i].t,&a[i].w);
        a[i].t = min(a[i].t,(int)1e5);
    }
    sort(a + 1,a + 1 + n,cmp);
    ll ans = 0;
    for(int i = 1;i <= n;i ++)
    {
        if(query(a[i].t) < a[i].t)
        {
            int l = 1,r = n,res;
            while(l < r)
            {
                int mid = l + r + 1 >> 1;
                if(query(a[i].t) - query(mid - 1) < a[i].t - mid + 1)
                {
                    l = mid;
                }
                else r = mid - 1;
            }
            update(l,1);
            ans += a[i].w;
        }
    }
    printf("%lld\n",ans);
    
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cold啦啦啦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值