zoukankan      html  css  js  c++  java
  • 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;
    }

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

  • 相关阅读:
    (转载)VS2010/MFC编程入门之三十七(工具栏:工具栏的创建、停靠与使用)
    (转载)VS2010/MFC编程入门之三十五(菜单:菜单及CMenu类的使用)
    (转载)VS2010/MFC编程入门之三十三(常用控件:标签控件Tab Control 下)
    (转载)VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)
    ubuntu下格式化u盘
    Android笔记之AppWidget
    Android笔记之ViewPager实现滑动页面
    Android笔记之获取布局中的多个子控件
    Android笔记之Actionbar制作选项卡(可滑动)
    Android笔记之Actionbar使用(二)
  • 原文地址:https://www.cnblogs.com/wendcn/p/12628115.html
Copyright © 2011-2022 走看看