戴德兰

题目描述

牛牛非常喜欢赶deadline。
输入n, c, d 一共有n个任务,第i个任务需要a[i]分钟完成
特别的,如果一个任务开始于最后d分钟(包括第c-d分钟),效率会变为双倍(耗时变为一半)
牛牛希望在c分钟内完成的任务尽可能多,问最多可以完成多少个任务。

更新1:

换句话说你可以想象成,数轴上从0到c的这段区间,然后要放置若干长度为a[i]的线段,放置的线段当然不能重合。
如果放置的线段的左端点 >= c-d,那么线段长度会变为a[i]/2。
在此基础上问最多可以放置多少个线段。

更新2:

首先原版题目是可以做的。
然后大概我数据出太弱了。(这教育我们出DP一定要出计数)
所以现在如果你实现成了,一个任务,在[c - d, c]这个区间内的部分,效率就会变成双倍。
并不需要满足左端点 >= c - d,当然如果左端点 < c - d,那么只有在[c - d, c]
这个区间内的部分,效率会变为双倍。
其余部分(在c - d之前的)效率不变。

更新3:

按照修改之前或修改之后的题意,都是可以通过本题的。
但是我觉得修改之后的题意更简单。
耗时变为一半是不取整的,如果出现0.5,那么就是0.5。
对于100%的数据,1 <= n <= 10000, 1 <= d <= c <= 100000, 1 <= a[i] <= c。
对于40%的数据,1 <= n <= 20。
对于70%的数据,1 <= n <= 1000, 1 <= c <= 1000。

输入描述:

输入第一行三个整数n, c, d。接下来一行n个整数a[i]。

输出描述:

输出一行一个整数,表示答案。

示例1

输入

4 10 5
8 10 1 2

输出

3

说明

牛牛可以先完成耗时为1和2的任务,花费3分钟。然后什么都不做等到第5分钟,开始完成耗时为10的任务。
这时因为开始的时间符合条件,这个耗时为10的任务只需要花费5分钟。
恰好可以赶在10分钟的限制内,完成3个任务。显然无论如何努力,也不能完成全部4个任务。
(经过修改之后这个解释就不那么对了,但是样例答案是没问题的。)

思路:

首先完成任务一定是完成耗时短的。所以一定是完成耗时最短的一些任务。 按照修改后的题意,直接认为一共有c+d的时间即可。然后把所有任务排序, 贪心即可。按照修改前的任务,那么选出的任务要满足如下条件:如果总和s > c+d,一定不可以如果总和s <= c 一定可以。设need = (s - c) * 2选出的 任务中,必须存在一个子集,这个子集的和在[need, 2 * d]之间。这个问题 是一个01背包,结合bitset做一下就可以了。

代码

#include<bits/stdc++.h>
using namespace std;
int n,c,d,a[10005],ans,sum;
int main()
{
    cin>>n>>c>>d;
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
            sort(a+1,a+1+n);
    while(ans!=n&&sum<c+d&&sum+a[ans+1]<c+d)
  sum+=a[++ans];
      printf("%d\n",ans);
    return 0;
}

来源:nkw

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值