• 一本通贪心集


    最优转载问题

    部分背包问题

    乘船问题

    选择不相交区间问题

    区间选点问题

    流水作业问题

    1425:【例题4】加工生产调度

    时间限制: 1000 ms         内存限制: 65536 KB提交数: 564     通过数: 130 

    【题目描述】

    某工厂收到了 nn 个产品的订单,这 nn 个产品分别在 A、B 两个车间加工,并且必须先在 A 车间加工后才可以到 B 车间加工。

    某个产品 ii 在 A,B 两车间加工的时间分别为Ai,BiAi,Bi。怎样安排这 nn 个产品的加工顺序,才能使总的加工时间最短。

    这里所说的加工时间是指:从开始加工第一个产品到最后所有的产品都已在 A,B 两车间加工完毕的时间。

    【输入】

    第一行仅—个数据 nn ,表示产品的数量;

    接下来 nn 个数据是表示这 nn 个产品在 A 车间加工各自所要的时间;

    最后的 nn 个数据是表示这 nn 个产品在 B 车间加工各自所要的时间。

    【输出】

    第一行一个数据,表示最少的加工时间;

    第二行是一种最小加工时间的加工顺序。

    【输入样例】

    5
    3 5 8 7 10
    6 2 1 4 9

    【输出样例】

    34
    1 5 4 2 3

    【提示】

    对于100%的数据, 0 < n < 10000,所有数值皆为整数。

    【题解】 

    贪心; 
    因为B机器在工作的时候,A机器还能够工作; 
    所以就这样; 
    对于A机器; 
    先找一个在A机器上加工时间短的产品; 
    让它在机器上加工完 
    尽早让B机器开始工作; 
    这样B机器和A机器它们的空闲时间就会最短了; 
    同时让B机器优先加工的产品时间尽量长一点; 
    这样同时在A机器上加工的产品就会尽可能地多; 
    总之就是让A机器和B机器的空闲时间尽可能地短;

    /*
        先找一个在A机器上加工时间短的产品;
        同时让B机器优先加工的产品时间尽量长一点;
    */


    上面这两句话就是关键了; 
    按照这个原则; 
    处理出m[i]=min(a[i],b[i]); 
    然后把m数组升序排; 
    然后顺序处理n个m[i]; 
    如果m是由a数组搞来的,就放在数据的最前(如果前面有元素了就尽可能靠前,否则放在序列的最后(如果最后也有元素了就尽量靠后); 
    如样例,N=5 
    (A1,A2,A3,A4,A5)=(3,5,8,7,10) 
    (B1,B2,B3,B4,B5)=(6,2,1,4,9) 
    则(m1,m2,m3,m4,m5)=(3,2,1,4,9) 
    排序之后为(m3,m2,m1,m4,m5) 
    处理m3:因为m3=B3,所以m3排在后面;加入m3之后的加工顺序为( , , , ,3); 
    处理m2:因为m2=B2,所以m2排在后面;加入m2之后的加工顺序为( , , ,2,3); 
    处理m1:因为m2=A1,所以m1排在前面;加入m1之后的加工顺序为(1, , ,2,3); 
    处理m4:因为m4=B4,所以m4排在后面;加入m4之后的加工顺序为(1, ,4,2,3); 
    处理m5:因为m5=B5,所以m5排在后面;加入m5之后的加工顺序为(1,5,4,2,3); 
    则最优加工顺序就是(1,5,4,2,3),最短时间34。显然这是最优解。 
    然后根据序列模拟出总的时间就好; 
    (B机器在工作的时候,A机器也可以继续加工其他产品哦); 

    //2018-08-03 20:09:13
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int N = 10001;
    
    int ans[N], a[N], b[N], m[N], s[N];
    int n;
    
    int main(){
        scanf("%d", &n);
        for(int i=1; i<=n; i++) scanf("%d", &a[i]);
        for(int i=1; i<=n; i++) scanf("%d", &b[i]);
        //**********
        for(int i=1; i<=n; i++){
            m[i] = min(a[i], b[i]);
            s[i] = i;
        }
        for(int i=1;i<=n-1; i++)
            for(int j=i+1; j<=n; j++)
                if(m[i] > m[j]){
                    swap(m[i], m[j]); swap(s[i], s[j]);
                }    
        int k=0, t=n+1;
        for(int i=1; i<=n; i++)
            if(m[i] == a[s[i]]){
                k++; ans[k] = s[i];
            }else{
                t--; ans[t] = s[i];
            }
        k = 0, t = 0;
        for(int i=1; i<=n; i++){
            k += a[ans[i]];
            if(t < k) t = k;
            t += b[ans[i]];
        }
        printf("%d
    ", t);
        for(int i=1; i<=n; i++) printf("%d ", ans[i]);
        printf("
    ");
    
        return 0;
    }

    带期限和罚款的单位时间任务调度

    1426:【例题5】智力大冲浪时间限制: 1000 ms   

          内存限制: 65536 KB提交数: 269     通过数: 199 

    【题目描述】

    小伟报名参加中央电视台的智力大冲浪节目。本次挑战赛吸引了众多参赛者,主持人为了表彰大家的勇气,先奖励每个参赛者m元。

    先不要太高兴!因为这些钱还不一定都是你的。接下来主持人宣布了比赛规则: 首先,比赛时间分为n个时段(n≤500),

    它又给出了很多小游戏,每个小游戏都必须在规定期限ti前完成(1≤ti≤n)。如果一个游戏没能在规定期限前完成,

    则要从奖励费m元中扣去一部分钱wi,wi为自然数,不同的游戏扣去的钱是不一样的。当然,每个游戏本身都很简单,

    保证每个参赛者都能在一个时段内完成,而且都必须从整时段开始。主持人只是想考考每个参赛者如何安排组织自己做游戏的顺序。

    作为参赛者,小伟很想赢得冠军,当然更想赢取最多的钱! 注意:比赛绝对不会让参赛者赔钱!

    【输入】

    输入共4行。

    第一行为m,表示一开始奖励给每位参赛者的钱;

    第二行为n,表示有n个小游戏; 第三行有n个数,分别表示游戏1~n的规定完成期限;

    第四行有n个数,分别表示游戏1~n不能在规定期限前完成的扣款数。

    【输出】

    仅1行。表示小伟能赢取最多的钱。

    【输入样例】

    10000
    7
    4 2 4 3 1 4 6
    70 60 50 40 30 20 10

    【输出样例】

    9950

    【提示】

    数据范围及提示:

    n≤500,1≤ti≤n

    思路:

    按罚款由大到小排序;

    然后从头开始吧任务安排在不超过期限且最接近期限的位置

    #include<iostream>
    #include<algorithm>
    using namespace std;
    struct pp{
        int w,t;
    };
    pp p[505];
    int vis[1000];
    bool cmp(pp p1,pp p2){
        if(p1.w!=p2.w)
        return p1.w>p2.w;
        else
        return p1.t>p2.t;
    }
    int main(){
        int sum,n,tt,ww;
        cin>>sum>>n;
        for(int i=1;i<=n;i++) cin>>p[i].t;
        for(int i=1;i<=n;i++) cin>>p[i].w;
        sort(p+1,p+n+1,cmp);
        for(int i=1;i<=n;i++){
            int j=p[i].t;
            while(vis[j]!=0){
                j--;
                if(j==0) break;
            }
            if(j==0){
                sum-=p[i].w;
                continue;
            }
            vis[j]=1;
        }
        cout<<sum<<endl;
        return 0;
    } 
  • 相关阅读:
    JSON 数据转换
    .NET LINQ 数据排序
    .NET LINQ标准查询运算符
    UML 序列图
    UML 类图
    UML 用例建模
    UML 概述
    .NET LINQ查询语法与方法语法
    .NET LINQ查询操作中的类型关系
    .NET 反射概述
  • 原文地址:https://www.cnblogs.com/yfr2zaz/p/10625267.html
Copyright © 2020-2023  润新知