5929: 家庭作业(贪心+并查集)

描述

 

老师在开学第一天就把所有作业都布置了,每个作业如果在规定的时间内交上来的话才有学分。每个作业的截止日期和学分可能是不同的。例如如果一个作业学分为10,要求在6天内交,那么要想拿到这10学分,就必须在第6天结束前交。

每个作业的完成时间都是只有一天。例如,假设有7次作业的学分和完成时间如下:

作业号 1 2 3 4 5 6 7
期限 1 1 3 3 2 2 6
学分 6 7 2 1 4 5 1

最多可以获得15学分,其中一个完成作业的次序为2,6,3,1,7,5,4,注意可能d还有其他方法。

你的任务就是找到一个完成作业的顺序获得最大学分。

输入

 

第一行一个整数N,表示作业的数量。

接下来N行,每行包括两个整数,第一个整数表示作业的完成期限,第二个数表示该作业的学分。

N<=1000000,作业的完成期限小于1000。

输出

 

输出一个整数表示可以获得的最大学分。保证答案不超过longint范围。

样例输入

样例输出

解题思路:按学分从大到小排,能完成就完成,  完成位置从后往前

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long ll;
 5 ll n,m,k;
 6 
 7 ll vis[1000005],arr[1000005];
 8 
 9 struct Node{
10     ll B,y;
11     bool operator<(const Node&e) const{
12         if(y!=e.y) return y>e.y;
13         return B<e.B;
14     }
15 
16 }A[1000005];
17 
18 ll find(int x){
19     if(vis[x]==0) return x;  //如果自己本身就是空的
20     arr[x]=find(arr[x]);
21     return arr[x];
22 }
23 
24 int main()
25 {
26     ios::sync_with_stdio(false);
27     cin>>n;
28     for(int i=1;i<=n;i++) cin>>A[i].B>>A[i].y,arr[i]=i-1;
29     sort(A+1,A+1+n);
30     ll sum=0;
31     for(int i=1;i<=n;i++){
32         int flag=0;
33         int temp=find(A[i].B);
34         if(temp){
35             vis[temp]=1;
36             sum+=A[i].y;
37             if(temp!=A[i].B){
38                 arr[A[i].B]=temp;
39             }
40         }
41     }
42     cout << sum << endl;
43     return 0;
44 }
View Code

 

 

原文地址:https://www.cnblogs.com/qq-1585047819/p/11228154.html