家庭作业
题解:
法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 }