• 2016级算法第二次上机-B.Bamboo的OS实验


    Bamboo的OS实验#

    分析##

    首先理解题意,要完成不同数量的不同命令,但是完成相同的命令之间必须有n个间隔,为使得时间最短,自然优先用其他命令来填充这n分钟的时间,由于数量少的命令可以用来填充空隙,所以次数最多的命令是起作用最大的。而且注意到,每次具体执行的是哪个命令并不影响时间,只与命令的数量有关(这有点贪心的思想,当预习吧)

    基于以上分析,可以有以下几种方法:

    1、按照命令数量从大到小排列,每次都是从数量最多的命令开始新一轮周期,这样是用时最少的。

    举个栗子,命令1 2 3 4 5各有6 1 1 1 1个,n=2,如果采用 1->2->3->4->5->1_->..这样就会导致数量最多的命令1每个都要有2个空的时间段来填充;最佳的思想是1->2->3->1->4->5,这样尚未进入周期的命令1才需要额外的时间填充。

    那么,将命令按数量从大到小排列后,总是选择当前数量最多的开始一轮周期,对选择的命令数量-1,时间++;每次这个周期一旦开始就要开始记录是否到n,周期结束后,要重新排序以保证从大到小的顺序,直到最多的命令也执行完毕,后面无需时间填充

    核心代码如下:
    static bool cmp(int i, int j)
    {
        return i>j;
    }
     int Map[35];
    int main()
    {
        int c,n,x;
        while(~scanf("%d",&x))
        {
             for(int i=0; i<35; i++)Map[i]=0;
            for(int i = 0; i<x; i++)
            {
                cin>>c;
                Map[c]++;
            }
            scanf("%d",&n);
            sort(Map,Map+35,cmp);
            int time = 0;
            while(Map[0]!=0)
            {
                int k =0;
                while(k<=n)
                {
                    if(k<31&&Map[k]>0)
                    {
                        Map[k]--;
                    }
                    else if(Map[0]==0)break;
                    k++;
                    time++;
                }
                sort(Map,Map+35,cmp);
            }
    
            printf("%d
    ",time);
        }
    }
    

    2、核心思路还是上面的思路,但是上面每次都保持数组从大到小的性质可以用优先队列来实现。只是可能要借助临时的数组temp[]来存储从优先队列中pop出的数据。

    3、也是大部分AC代码采用的思路。其实不管命令有多少,n等于几,这些命令总是要做完的,所花的时间一定是>=x的。所以只需要看需要填充多少思考人生时间。

    上图:
    https://coding.net/s/2791e979-c082-43b9-9b28-e43496fe9c76
    //用画图画的,专治强迫症
    深蓝色的就是用命令填充的,浅蓝色即为“思考人生”时间。
    显然总的时间=任务数+思考时间
    当只有第一排的1而后面全是浅蓝色时,是需要空闲时间最多的情况,max_num=n*(最多的命令数-1),因为最后一轮后面是不填充的,所以-1;
    我们要做的就是从这个最大值里逐列减去已经有命令的格子。

    核心代码如下,可以看图体会:
     int Map[35];
        for(int i=0; i<35; i++)Map[i]=0;
        for(int i = 0; i<tasks.size(); i++)
        {
            Map[tasks[i]]++;
        }
        sort(Map,Map+35,cmp);
        int max = Map[0]-1;
        int slot = max*n;
        for(int i = 1;i<31;i++)
        {
            slot -= min(Map[i],max); 
        }
            int ans;
            if(slot>0)ans = slot+tasks.size();
            else ans = tasks.size();
    
  • 相关阅读:
    App_Data文件夹的用处.
    .net工资管理系统 C#2.0开发
    红警2尤里的复仇 无限金钱 无限电力修改器
    用bho方式拦截中国电信流氓广告
    仙剑4按键取钱的东东。
    多浏览器测试的利器IETester,自带IE5.5,IE6,IE7,IE8等多个内核.
    dataGridView使用指南系列一、回车换行或换列完美解决方案
    红警2共和国之辉无限金钱修改器,造东西不花钱还赚钱。
    UpdatePanel控件,你真的会用了吗?
    XP+WIN7共享动态磁盘的一点收获
  • 原文地址:https://www.cnblogs.com/AlvinZH/p/7761372.html
Copyright © 2020-2023  润新知