4.5 10346 带价值的作业安排问题
Description
已知n项作业E={1, 2, … ,n} 需要完成,只有一台机器,同一时刻至多完成一个作业,
而且每项作业需要的时间都是单位时间1。第k项作业要求在时间fk时刻执行并完成,而且
完成这项作业将获得效益pk,(k=1, 2, … , n)。
E的子集称为相容的,如果它们可以被安排由一台机器完成。
带限期和价值的作业安排问题就是:要在所给的作业集合中选出总效益值最大的相容子集,
请输出最大的总效益值。
输入格式
输入3行:
第一行,一个数n,表示n个作业(n<10000)。
第二行,n个正数,表示这n个作业的应执行的时间点。
第三行,n个正数,表示这n个作业的效益值。
输出格式
输出:相容作业子集所获得的最大总效益。
例如:7个作业
时间点和效益值分别是:
1 8 8 5 9 3 5
20 25 30 7 18 10 18
则:可以获得的最大总效益为:20 + 30 +18 + 10 + 18 = 96
输入样例
7
1 88 5 9 3 5
2025 30 7 18 10 18
输出样例
96
提示
贪心法
1)按价值从高到低排序所有作业;
2)纳入作业1;
3)从作业2到作业n,逐个检测是否和已经纳入的作业相容,相容则添入“相容作业集合”中。
此处,相容的判断不同于书上的活动安排问题,因为每个作业仅需一个单位时间就可完成,
所以每当判断一个新的作业是否可以加入进已有的相容作业集合,就看这个新的作业是否
能在其执行时间内被安排。
#include
void sort(int f[],int p[],int n)
{
for(int i=0; i { for(int j=i+1; j { if(p[i]
{ int temp =p[i]; p[i]=p[j]; p[j]=temp; temp=f[i]; f[i]=f[j]; f[j]=temp; } } } } bool inSet(int f[],int c) //f是表示时间 { for(int i=0; i { if(f[i]==f[c]) return true; } return false; } void scheduling(int f[],int p[],int n) { int sum=0; for(int c=0; c { if(!inSet(f,c)) //判断时间不相同的话(false)就相加 { sum+=p[c]; } } printf("%d",sum); } int main() { int n,f[10000],p[10000]; scanf("%d",&n); for(int i=0; i { scanf("%d",&f[i]); //时间点 } for(int i=0; i { scanf("%d",&p[i]); //效益值 } sort(f,p,n); scheduling(f,p,n); return 0; }