1430:家庭作业

时间:2019-08-20
本文章向大家介绍1430:家庭作业,主要包括1430:家庭作业使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

家庭作业链接

1430:家庭作业


时间限制: 1000 ms         内存限制: 65536 KB
提交数: 1315     通过数: 286

【题目描述】

老师在开学第一天就把所有作业都布置了,每个作业如果在规定的时间内交上来的话才有学分。每个作业的截止日期和学分可能是不同的。例如如果一个作业学分为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行,每行包括两个整数,第一个整数表示作业的完成期限,第二个数表示该作业的学分。

【输出】

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

【输入样例】

7
1 6
1 7
3 2
3 1
2 4
2 5
6 1

【输出样例】

15
分析:这题是需要用到贪心,但如果单纯的贪心的话,在衔接前面的话(如果是单纯的寻找,或者模拟)将会超时;
这里就需要用到链表优化将上一轮的衔接上,操作一次只需1次,有点像并查集里的压缩路径优化;
最后请自行思考,自己不要看着打,要学会方法。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
inline int read()
{
 char ch=getchar();int x=0,f=1;
 while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
 while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
 return x*f;
}
int pre[1000010];
bool vis[1000010];//位置判断
struct node
{
 int pt,day;
}a[1000010];
bool cmp(node a,node b)
{
 if(a.pt==b.pt) //优先分数高的
  return a.day<b.day;
 return a.pt>b.pt;
}
int ans;
//自闭的链表
int pd(int day)
{
 if(!vis[day])
  return day;
 return pre[day]=pd(pre[day]);//往下找直到空位
 }
int main()
{
 int n=read();
 int i,j;
 for(i=1;i<=n;++i)
  a[i].day=read(),a[i].pt=read();
 
 for(i=1;i<=n;++i)//链表预备
 {
  pre[i]=i-1;
  vis[i]=false;
 }
 sort(a+1,a+n+1,cmp);
 
 for(i=1;i<=n;++i)
 {
  int gg=pd(a[i].day);
  if(gg==0)//到零的话说明满了
   continue;
  vis[gg]=true;
  ans+=a[i].pt;
 }
 printf("%d",ans);
 return 0;
}

原文地址:https://www.cnblogs.com/Gooyu/p/11386045.html