任务调度问题1—贪心算法

这个问题是《算法导论》上的一个经典的贪心算法问题——单处理器上具有期限和惩罚的单位时间任务调度问题,目标是使惩罚最小。

  输入:第一行一个数n,接下来第2行到第n+1行,第i行分别是d[i]和w[i],其中d[i]表示第i个任务的时限,w[i]表示第i个任务的惩罚,每个任务的完成时间为单位时间。

  输出:一行一个数,为最小惩罚。

  题解:

  令集合S为所有任务的集合,A为一个任务集合,其中所有的任务满足条件:存在某种调配方式,使得所有任务能在期限前完成,又令l为所有A集合的集合。可以证明,序对M=(S,l)是一个拟阵,于是,可以采用贪心算法解决它。同时,一个任务集合R属于l,当且仅当它满足下列条件:

 R中在期限在不大于t的任务不大于t个。

  于是算法就出来了:先以w[i]为关键字进行排序,再进行枚举:保持一个数组record[i]保存当前集合中时限在不大于i的任务个数,对于每一个任务ai,将d[i]之后的record更新(加1),若有一个d[j]不满足条件,则继续检查下一个,反之,将它的惩罚从总惩罚中减去。最后得到的总惩罚即最小惩罚。

代码:

 1 #include <iostream>
 2 #include <fstream>
 3 using namespace std;
 4 ifstream fin("TSP.in");
 5 ofstream fout("TSP.out");
 6 int w[2001],d[2001]; //w[i]指第i号任务的逾期惩罚,d[i]指第i号任务的期限,每个任务都是单位时间;
 7 int record[2001];
 8 int Max,ans;
 9 int partion(int *a,int start,int end)
10 {
11     int i=start,j=start-1,t=0;
12     for(i=start;i<=end;i++)
13     {
14       if(a[i]>=a[end])
15       {
16         j++;
17         t=a[i];
18         a[i]=a[j];
19         a[j]=t;
20         t=d[i]; 
21         d[i]=d[j];
22         d[j]=t;
23       }
24     }
25     return j;
26 }
27 int quicksort(int *a,int start,int end)
28 {
29 if(start>=end)
30 return 0;
31 int j=partion(a,start,end);
32 quicksort(a,start,j-1);
33 quicksort(a,j+1,end);
34 return 0;
35 }
36 int main()
37 {
38 int n=0,i=0,j=0;
39 fin>>n;
40 for(i=1;i<=n;i++)
41 {
42 fin>>d[i]>>w[i];
43 }
44 quicksort(w,1,n);
45 for(i=1;i<=n;i++)
46 {
47 if(d[i]>=n+1)
48 {
49 Max+=w[i];
50 continue;
51 }
52 for(j=d[i];j<=n;j++)
53 {
54 if(record[j]+1>j)
55 break;
56 }
57 if(j==n+1)
58 {
59 for(j=d[i];j<=n;j++)
60 record[j]++;
61 Max+=w[i];
62 }
63 }
64 for(i=1;i<=n;i++)
65 ans+=w[i];
66 ans-=Max;
67 fout<<ans<<endl;
68 }

  拟阵作为一种高级结构,是在贪心算法的研究中所必须掌握的,同时也由于它的难度较大,更需要我们来认真学习。

  更多关于拟阵的内容,请参见《算法导论(第二版)》的“贪心算法”一章。

转载于:https://www.cnblogs.com/kliner/archive/2012/10/12/sfdl_greedy.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值