任务调度 简单贪心

题意:

    有N个任务,每个任务都花费一个单位的时间来完成,每个任务都有规定的时间期限,超出期限完成则要罚款。求所能使罚款最小的任务组合及最小罚款金额。

   

输入:

    一个整数N代表任务个数,下面N行分别有两个整数,第一个为时间期限,第二个为超时罚款金额。

输出:

    期限内完成的任务编号,期限外完成任务编号,罚款数。


    本题关键在罚款金额,所以要尽可能的使罚款金额大的任务先完成,对任务根据罚款金额从大到小排序,依次处理各个任务。得到可提前完成的任务后,对任务根据时间期限排序,使期限大的任务尽可能的靠后,这样能保证提前完成的任务数量最大。


代码:

#include<iostream>
#include<cstring>
using namespace std ;

typedef struct test {
    int k, d, w ;
}text ;

int main(){
    text tlist [100], list [100] ;
    int p [100] ;
    int temp[1010] ;
    memset(temp, 0, sizeof(temp)) ;
    int n, i, j, t ;
    cin >> n ;
    for(i=1; i<=n; i++){
        cin >> tlist[i].d >> tlist[i].w ;
        tlist[i].k = i ;
        temp[tlist[i].w] ++ ;
    }
    for(i=2; i<=1000; i++)          //计数排序
        temp[i] += temp[i-1] ;
    for(j=n; j>=1; j--){
        list[temp[tlist[j].w]] = tlist[j] ;
        temp[tlist[j].w] -- ;
    }
    int num = 0 ;                 //提前完成任务的个数
    for(i=n; i>=1; i--){            //由于计数排序是从小到大排的,所以任务从大到小搜索
        t = 0 ;
        for(j=1; j<=num; j++)
            if(list[p[j]].d<=num)
                t ++ ;
        if(t<list[i].d){     //若第i个任务的期限小于以确定的提前完成任务个数,将第i个加入可提前完成任务序列中
            num ++ ;
            p[num] = i ;
            list[i].k = -list[i].k ;
            j = num ;
            while(j>1){             //对提前完成的任务时间期限从小到大排
                if(list[p[j]].d<list[p[j-1]].d){
                    t = p[j] ;
                    p[j] = p[j-1] ;
                    p[j-1] = t ;
                    j -- ;
                }
                else break ;
            }
        }
    }
    for(i=1; i<=num; i++)
        cout << -list[p[i]].k << " " ;
    cout << endl ;
    t = 0 ;
    for(i=1; i<=n; i++)
        if(list[i].k>0){
            cout << list[i].k << " " ;
            t += list[i].w ;
        }
    cout << endl << t ;
    return 0 ;
}

转载于:https://www.cnblogs.com/xiaolongchase/archive/2011/08/14/2137842.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值