题目描述
牛牛非常喜欢赶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