1430:家庭作业
1430:家庭作业(一本通网站原题链接)
【分析】
首先:这些作业由于时间关系,可能做不完,意味着必须放掉一些,放弃哪些作业呢?由于所有作业都是一天完成,显然得放弃得分低一点的。这里当然是个贪心策略,先做分值高的,再做分值低的。后面的作业没时间做了就放弃。其次:作业只分是否完成,何时完成没有关系,只要在期限内就好。所以我们可以再“贪心“一次——靠着期限从后往前排,这样能兼顾分值高期限长和分值稍低期限短的作业。再次:本题没说明数据规模,那只有朝着可能的最大数据量而做。显然本题存在排序,数据一般定格在百万数据规模,再大数组都难定义,排序也有难度了。最后:每项作业都有三个数据,序号、期限、学分,初步考虑用结构体来做。我们每次都要取出余下最大学分项,我采用堆来存数据。附上代码
//1430:家庭作业 #include<iostream> #include<queue> using namespace std; int const N=1e6+5; bool p[N]; struct data{ int f,t; bool operator < (const data x) const{ return f<x.f; } }tmp; priority_queue<data> q; int n,ans; int main(){ cin>>n; for(int i=1;i<=n;i++) { cin>>tmp.t>>tmp.f; q.push(tmp); } while(!q.empty()) { tmp=q.top(); q.pop(); for(int i=tmp.t;i>0;i--) if(!p[i]) { p[i]=true,ans+=tmp.f; break; } } cout<<ans; return 0; }
提交后,出了些状况:50分;其他超时。看来这个数据量还真的大,真有百万数据量,输入优化是必须的,加入ios::sync_with_stdio(false);优化输入效率,提交有改善,70分。还有三个点超时。想想还能在哪挤时间呢?自设稍大的测试数据跟踪过程发现当前面期限排满后,程序依然会依次扫描所有时间轴,如果终止扫描的时间后推,那就不用把前面排满的时间轴再去扫描,大量的数据可以节约大把时间。来吧,干就完了。
【AC代码】
//1430:家庭作业 #include<iostream> #include<queue> using namespace std; int const N=1e6+5; bool p[N]; struct data{ int t,f; bool operator < (const data x) const{ return f<x.f; } }tmp; priority_queue<data> q; int n,ans,maxn,tt; int main(){ ios::sync_with_stdio(false); cin>>n; for(int i=1;i<=n;i++) { cin>>tmp.t>>tmp.f; q.push(tmp); } while(!q.empty()) { tmp=q.top(); q.pop(); int i; for(i=tmp.t;i>tt;i--) if(!p[i]) { p[i]=true,ans+=tmp.f; break; } if(i==tt&&tt<tmp.t)tt=tmp.t; } cout<<ans; return 0; }
如有不妥,欢迎评论,谢谢你的阅读!