CF-1072-C. Cram Time(贪心,数学)

本文详细解析了Codeforces比赛题目CF-1072-C的解决方案,介绍了如何在有限的时间内分配任务以实现两天内完成最多任务数的目标。通过寻找最大k使得k*(k+1)/2≤总时间,再逆序遍历任务列表,优先安排在第一天可完成的任务,剩余任务安排在第二天。

CF-1072-C. Cram Time

http://codeforces.com/contest/1072/problem/C

题意:

第一天有 a 小时,第二天有 b 小时。第 k 个任务需要 k 个小时来完成。任务不能隔天做(即第一天开始,第二天结束)。问这两天分别可以最多完成多少任务,并输出。

分析:

  • 既然总共有a+b个小时,那么每个任务所需时间越少,任务数越多。即我们要找到一个最大的k\(k*(k+1)/2 \le (a+b)\) 即前k个任务的所需时间和小于等于a+b
  • 找到k之后,从k倒序遍历。遇到可以在第一天完成的(即当前任务所需时间小于a),就在第一天完成,然后第一天时间 a -= i,除去第一天完成的任务,剩下的就是第二天的。
typedef long long ll;
int main() 
{
    //因为后面计算k的前缀和可能超int,所以这里k和a,b都为longlong
    ll a,b,k=0;
    cin>>a>>b;
    vector<int> a1,b1;
    //这里有个小细节,要保留最大的具有可行性的k。
    while((k+2)*(k+2)/2 <= a+b) k++;
    for(int i=k;i>=1;i--)
    {
        //若可在第一天内完成
        if(a>=i)
        {
            a-=i;
            a1.push_back(i);
        }
        else b1.push_back(i);
    }
    printf("%d\n",a1.size());
    for(auto x : a1)printf("%d ",x);
    puts("");
    printf("%d\n",b1.size());
    for(auto x : b1)printf("%d ",x);
    puts("");
    return 0;
}

转载于:https://www.cnblogs.com/1625--H/p/9829027.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值