家庭作业

题解:

法1:堆

将作业按时间由大到小排序

枚举时间,将该时间的作业放入堆

在此时间取出堆中的一个最大值

法二:并查集

先贪心,将价值从大到小排序,每次判断di前有无空格,这可以用并查集高效实现

每次占一格子,将其与前一个格子合并(路径压缩)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 struct Node
 7 {
 8     int d,p;
 9 }a[100001];
10 bool cmp(Node a,Node b)
11 {
12     return (a.d>b.d);
13 }
14 long long sum,heap[100001],n,ans;
15 void add(int x)
16 {int pos,nxt;
17     sum++;
18     heap[sum]=x;
19     pos=sum;
20     while (pos/2)
21     {
22         nxt=pos/2;
23         if (heap[pos]>heap[nxt]) 
24         {
25             int k=heap[pos];
26             heap[pos]=heap[nxt];
27             heap[nxt]=k;
28         }
29         else break;
30      pos=nxt;
31     }
32 }
33 void pop()
34 {int pos,nxt;
35     heap[1]=heap[sum];
36     sum--;
37     pos=1;
38     while (pos*2<=sum)
39     {
40         nxt=pos*2;
41          if (nxt+1<=sum&&heap[nxt+1]>heap[nxt]) nxt++;
42          if (heap[nxt]>heap[pos])
43          {
44              int k=heap[pos];
45             heap[pos]=heap[nxt];
46             heap[nxt]=k;
47          }
48          else break;
49         pos=nxt;
50     }
51 }
52 int main()
53 {int i,maxn=0,j;
54 freopen("2.in","r",stdin);
55 freopen("2.out","w",stdout);
56     cin>>n;
57     for (i=1;i<=n;i++)
58     {
59         scanf("%d%d",&a[i].d,&a[i].p);
60         maxn=max(maxn,a[i].d);
61     }
62      sort(a+1,a+n+1,cmp);
63      j=1;
64      for (i=maxn;i>=1;i--)
65      {
66          while (a[j].d>=i&&j<=n)
67          {
68              add(a[j].p);
69              j++;
70         }
71         if (sum)
72         {
73          ans+=heap[1];
74           pop();
75         }
76      }
77      cout<<ans; 
78 }
原文地址:https://www.cnblogs.com/Y-E-T-I/p/7163169.html