描述
老师在开学第一天就把所有作业都布置了,每个作业如果在规定的时间内交上来的话才有学分。每个作业的截止日期和学分可能是不同的。例如如果一个作业学分为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 }