【Loj #10008. 「一本通 1.1 练习 4」家庭作业】题解
题目链接
题目
老师在开学第一天就把所有作业都布置了,每个作业如果在规定的时间内交上来的话才有学分。每个作业的截止日期和学分可能是不同的。例如如果一个作业学分为 101010,要求在 666 天内交,那么要想拿到这 101010 学分,就必须在第 666 天结束前交。
每个作业的完成时间都是只有一天。例如,假设有 7 次作业的学分和完成时间如下:
作业号 期限 学分
111 111 666
222 111 777
333 333 222
444 333 111
555 222 444
666 222 555
777 666 111
最多可以获得 151515 学分,其中一个完成作业的次序为 2,6,3,1,7,5,42,6,3,1,7,5,42,6,3,1,7,5,4,注意可能还有其他方法。
你的任务就是找到一个完成作业的顺序获得最大学分。
思路
按学分从大到小排序,优先放在最后的时间。
然后这是 \(O(n^2)\),会炸。
于是我们可以套个并查集。
Code
// Problem: #10008. 「一本通 1.1 练习 4」家庭作业
// Contest: LibreOJ
// URL: https://loj.ac/p/10008
// Memory Limit: 512 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
//#define M
//#define mo
//#define N
struct node
{
int t, v;
}a[1000010];
int n, m, i, j, k;
int f[700010];
bool cmp(node x, node y)
{
return x.v>y.v;
}
int dfs(int x)
{
if(f[x]==x) return x;
return f[x]=dfs(f[x]);
}
signed main()
{
// freopen("tiaoshi.in", "r", stdin);
// freopen("tiaoshi.out", "w", stdout);
n=read();
for(i=1; i<=700000; ++i) f[i]=i;
for(i=1; i<=n; ++i)
a[i].t=read(), a[i].v=read();
sort(a+1, a+n+1, cmp);
for(i=1; i<=n; ++i)
{
j=dfs(a[i].t);
if(j) k+=a[i].v, f[j]=f[j-1];
}
printf("%lld", k);
return 0;
}
本文来自博客园,作者:zhangtingxi,转载请注明原文链接:https://www.cnblogs.com/zhangtingxi/p/15643572.html