5929: 家庭作业
时间限制(普通/Java):6000MS/18000MS 内存限制:65536KByte
总提交: 223 测试通过:44
描述
老师在开学第一天就把所有作业都布置了,每个作业如果在规定的时间内交上来的话才有学分。每个作业的截止日期和学分可能是不同的。例如如果一个作业学分为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.学分多的一定要拿。
2.每次要拿学分的作业一定要在离它期限最近且没被使用过的天数。
并查集:
可以用递归写,这边没用递归可以在2MS内跑完,用递归得5秒,看题目给的时长,用一个pre数组来标记某天有没有被使用过,如果没指向自己,当被使用过后会指向前一天,当前一天也被使用后要路径压缩。
优先队列:
找到所有作业中最大的一天,排序完后从最大的一天开始遍历,如果当前作业能够在今天完成,加入队列,加完后取最大价值的出来就好了,其实差不多。
并查集
#include<bits/stdc++.h>
using namespace std;
const int maxn=1000005;
const int maxn1=700005;
int pre[maxn1];
struct node{
int t,val; //结构体,时间和价值
}q[maxn];
bool cmp(node a,node b){
return a.val>b.val; // 价值大的排在前面
}
int getfather(int x){
int son=x,tmp;
while(pre[x]!=x){ //当前的父亲不指向自己时,继续找
x=pre[x];
if(x==0) //当找到0说明当前任务的最大期限内所以的时间都被使用完了
return 0;
}
while(son!=x){
tmp=pre[son]; //路径压缩,把父亲节点的所有儿子都设为x-1
pre[son]=x-1;
son=tmp;
}
pre[x]=x-1; //父亲节点用完后也得指向x-1
return 1;
}
int main(){
int n;
__int64 ans=0;
scanf("%d",&n);
for(int i=0;i<maxn1;i++)
pre[i]=i; //初始化所有天数指向自己
for(int i=0;i<n;i++)
scanf("%d%d",&q[i].t,&q[i].val);
sort(q,q+n,cmp);
for(int i=0;i<n;i++) if(getfather(q[i].t)) ans+=q[i].val;//如果未被使用
printf("%I64d",ans);
}
优先队列
#include<bits/stdc++.h>
using namespace std;
const int maxn=1000005;
struct node{
int t,val;
}e[maxn];
bool cmp(node a,node b){
return a.t>b.t;
}
priority_queue<int>q;
int main(){
int n,m=0;
__int64 ans=0;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d%d",&e[i].t,&e[i].val); // 输入排序
m=max(m,e[i].t);
}
sort(e,e+n,cmp);
int l=0;
for(int i=m;i>0;i--){
while(e[l].t>=i&&l<n) q.push(e[l++].val); //遍历今天能做的所有作业
if(!q.empty()){ //取出价值最大的
ans+=q.top();
q.pop();
}
}
printf("%I64d\n",ans);
}
本文探讨了一种针对作业调度的算法,旨在最大化学生在有限时间内可获得的学分。通过对作业的学分和截止日期进行分析,采用贪心策略与并查集或优先队列实现,以确保在遵守时间限制的同时,选择价值最高的作业完成。
1063

被折叠的 条评论
为什么被折叠?



