题意简要的说就是N件任务,每件任务i有期限d
i和收益p
i,每个时刻能同时做n个任务,求最大获益。
贪心策略是这样的:先对任务按照收益排序,然后尽可能地往靠近期限的地方丢,这里用到并查集来优化,如果某个时刻已经被占用n次了,则将其与前面一个格子合并,具体细节注意下就可以了
1 # include <cstdio>
2 # include <algorithm>
3 using namespace std;
4 struct node
5 {
6 int p,d;
7 }data[10005];
8 bool cmp(const node &a,const node &b)
9 {
10 return a.p>b.p;
11 }
12 int set[10005];
13 int co[10005];
14 int find(int pos)
15 {
16 if(set[pos]==pos)
17 return pos;
18 else return set[pos]=find(set[pos]);
19 }
20 int num,l;
21 int main()
22 {
23 while(scanf("%d%d",&num,&l)!=EOF)
24 {
25 for(int i=0;i<num;i++)
26 scanf("%d%d",&data[i].p,&data[i].d);
27 for(int i=0;i<=10000;i++)
28 set[i]=i,co[i]=l;
29 sort(data,data+num,cmp);
30 int total=0;
31 for(int i=0;i<num;i++)
32 {
33 if(co[find(data[i].d)]==0) continue;
34 else
35 {
36 co[find(data[i].d)]--;
37 total+=data[i].p;
38 if(!co[find(data[i].d)])
39 {
40 for(int j=data[i].d;j>=0;j--)
41 {
42 if(co[find(j)])
43 {
44 set[find(data[i].d)]=find(j);
45 break;
46 }
47 }
48 }
49 }
50 }
51 printf("%d\n",total);
52 }
53 return 0;
54 }
55