1430:家庭作业
题解
本题和智力大冲浪可以说有异曲同工之喵啊,唯一不同的是本题要加上一步优化,防止超时
因为是保证学分尽量多,所以先按学分从大到小排序,把作业在规定期限内尽量靠后排
接下来讲一讲优化(借鉴了一下度娘找到的大佬的博客)
比如说我有三个作业
[ 2 6 ] [ 2 5 ] [ 2 4 ]
我把第一个作业安排到2 ,第二个作业安排到 1,那么第三个作业就不用考虑了,因为没有办法继续布置了,也就是1~line[ ].t 都已经排满了,那么我们标记一个dislike,表示从1~dislike都不可以安排作业了
如果不加优化,每个都需要for循环判断,很浪费时间
代码
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #include<string> #include<queue> #include<functional> using namespace std; int n,dislike; long long ans; bool vis[1000001],fa[1000001]; struct node { int t,w; }line[1000001]; bool cmp(node x,node y) { return x.w >y.w ; } bool pan(int x) { for(int i=line[x].t ;i>=1;i--) { if(vis[i]==0) { vis[i]=1; return 1; } } dislike=line[x].t ; //不可以继续安排作业了 return 0; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d%d",&line[i].t ,&line[i].w ); sort(line+1,line+n+1,cmp); memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++) { if(line[i].t <dislike) continue; //在1~dislike区间里都不可以安排作业了 if(pan(i)) ans+=line[i].w ; } printf("%ld",ans); return 0; }