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;
}

如有不妥,欢迎评论,谢谢你的阅读!

猜你喜欢

转载自www.cnblogs.com/wendcn/p/12628115.html