一、工程代码及算法设计注释
--------------------------------------------------mainframe.h----------------------------------------------
#ifndef JLU_CCST_MAINFRAME_H
#define JLU_CCST_MAINFRAME_H
#include <vector>
struct Job{
int cpu,memory,arrive,deadline,reward,bonus,punishment;
bool isExecuted;
Job(int c=0,int m=0,int a=0,int d=0,int r=0,int b=0,int p=0,bool i=false):cpu(c),memory(m),arrive(a),
deadline(d),reward(r),bonus(b),punishment(p),isExecuted(i) {} ;
/**
如果比job小,则返回-1;否则返回1.(由于本题中job的特性,任意2个job不会相等)
*/
int compare(const Job& job){
if(arrive<job.arrive)
return -1;
if(arrive==job.arrive&&bonus<job.bonus)
return -1;
return 1;
}
};
extern int caculateIncome(std::vector<Job>& jobList,int nCPU,int nMemory,int timeLineF);
extern void testCaculateIncome();
#endif//JLU_CCST_MAINFRAME_H
-------------------------------------------------- mainframe.cpp ----------------------------------------------
/**
题目来源:浙大ACM在线测试——ZOJ,题目编号1012,题名"Mainframe"
URL:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1012
Author:hellogdc<gdcjlu@163.com>
Finish Time:2014.01.10
*/
/**
问题分析:
该题的关键是要将所有job排一列,然后从头开始逐个执行这些job。
排序的指标有2个:主指标为到达时间,次指标为报酬。因为每个任务的报酬
都不一样,所以任意2个job之间都有一个“先后”关系,所以这是一个全序关系。
job的执行:由于CPU及内存的限制,所以job可能不会是按照排序好的队列顺序
执行,因为排在前面的job可能因为CPU和内存限制导致执行不了,从而让位于
后面的一些对资源要求较小的任务。
算法设计:
1. 基于任务到达时间和报酬,对所有任务进行排序,得到一个有序列表jobList.
2. 如果jobList非空,则循环执行下面语句。
2.1 设置当前时间:将队列最前面的job的到达时间设置为当前时间,同时设置资源:m=M,n=N。
2.2 遍历jobList,找出合适的job进行执行。
2.2.1 如果该队列元素的到达时间比当前时间大,则退出该循环,结束寻找。
2.2.2 对于所有到达时间等于当前时间的job,做如下处理:
如果当前的剩余资源能满足该job的要求,则该job将被执行,将其从队列中剔除,
计算费用,更新当前剩余资源。否则,将其到达时间加1(这是为了能在下一小时被优先检测).
3. 统计那些Ui<=F但确未被执行的job,同时计算费用。
*/
#include <iostream>
#include <vector>
#include "mainframe.h"
using namespace std;
int caculateIncome(vector<Job>& jobList,int nCPU,int nMemory,int timeLineF){
//1. 递减排序
for(int i=0;i<jobList.size()-1;i++){
for(int j=i+1;j<jobList.size();j++){
if(jobList[i].compare(jobList[j])==-1){
Job tmp=jobList[j];
jobList[j]=jobList[i];
jobList[i]=tmp;
}
}
}
//2. 计算那些被执行的job所产生的的费用
int income=0;
int head=0;
while(true){
//2.1 找到队列中尚未执行的“首席”job
while(head<jobList.size()){
if(!jobList[head].isExecuted)
break;
head++;
}
if(head==jobList.size())
break;
int currentTime=jobList[head].arrive;
if(currentTime>timeLineF-1)
break;
int nC=nCPU,nM=nMemory;
bool isFound=false;
//2.2 遍历jobList,找出合适的job进行执行。
for(int i=head;i<jobList.size();i++){
if(jobList[i].isExecuted)
continue;
//2.2.1 如果该队列元素的到达时间比当前时间大而且已到合适的job来执行,
// 则退出该循环,不再寻找。
if(jobList[i].arrive>currentTime)
break;
//2.2.2 如果队列元素的到达时间等于当前时间,且当前的资源量能满足该job的要求,
// 则该job将被执行,将其从队列中剔除。计算费用。更新当前剩余资源。
// 否则,将其到达时间加1(这是为了能在下一小时被优先检测).
if( jobList[i].arrive=currentTime){
if(jobList[i].cpu<=nC&&
jobList[i].memory<=nM ){
nC-=jobList[i].cpu;
nM-=jobList[i].memory;
isFound=true;
jobList[i].isExecuted=true;
income+=jobList[i].reward;
if(currentTime+1<jobList[i].deadline)
income+=( (jobList[i].deadline-currentTime-1)*jobList[i].bonus );
else
income-=( (currentTime+1-jobList[i].deadline)*jobList[i].punishment );
}else
jobList[i].arrive++;//下次执行
}
}
}
//3. 统计那些Ui<=F但确未被执行的job
for(int i=head;i<jobList.size();i++){
if( (!jobList[i].isExecuted)&&
jobList[i].deadline<=timeLineF )
income-=( (timeLineF-jobList[i].deadline)*jobList[i].punishment );
}
return income;
}
/Test Case///
void testCaculateIncome(){
vector<Job> jobList;
int cpu,memory,timelineF;
//
cpu=4;memory=256;timelineF=10;
jobList.push_back(Job(1,16,2,3,10,5,6));
jobList.push_back(Job(2,128,2,4,30,10,5));
jobList.push_back(Job(2,128,2,4,20,10,5));
int income=caculateIncome(jobList,cpu,memory,timelineF);
cout<<"Income="<<income<<endl;
}
-------------------------------------------------- main.cpp ----------------------------------------------
#if 0
#include "mainframe.h"
int main(){
testCaculateIncome();
}
#endif
二、 提交给ZOJ的代码——算法核心代码
注:蛋疼的报了“Wrong Answer”错误。还未解决。
--------------------------------------------------submit_main.cpp----------------------------------------------
/**
all codes are copied from mainframe.cpp
*/
#include <iostream>
#include <vector>
using namespace std;
struct Job{
int cpu,memory,arrive,deadline,reward,bonus,punishment;
bool isExecuted;
Job(int c=0,int m=0,int a=0,int d=0,int r=0,int b=0,int p=0,bool i=false):cpu(c),memory(m),arrive(a),
deadline(d),reward(r),bonus(b),punishment(p),isExecuted(i) {} ;
int compare(const Job& job){
if(arrive<job.arrive)
return -1;
if(arrive==job.arrive&&bonus<job.bonus)
return -1;
return 1;
}
};
int computeIncome(vector<Job>& jobList,int nCPU,int nMemory,int timeLineF){
for(int i=0;i<jobList.size()-1;i++){
for(int j=i+1;j<jobList.size();j++){
if(jobList[i].compare(jobList[j])==-1){
Job tmp=jobList[j];
jobList[j]=jobList[i];
jobList[i]=tmp;
}
}
}
int income=0;
int head=0;
while(true){
while(head<jobList.size()){
if(!jobList[head].isExecuted)
break;
head++;
}
if(head==jobList.size())
break;
int currentTime=jobList[head].arrive;
if(currentTime>timeLineF-1)
break;
int nC=nCPU,nM=nMemory;
bool isFound=false;
for(int i=head;i<jobList.size();i++){
if(jobList[i].isExecuted)
continue;
if(jobList[i].arrive>currentTime)
break;
if( jobList[i].arrive=currentTime){
if(jobList[i].cpu<=nC&&
jobList[i].memory<=nM ){
nC-=jobList[i].cpu;
nM-=jobList[i].memory;
isFound=true;
jobList[i].isExecuted=true;
income+=jobList[i].reward;
if(currentTime+1<jobList[i].deadline)
income+=( (jobList[i].deadline-currentTime-1)*jobList[i].bonus );
else
income-=( (currentTime+1-jobList[i].deadline)*jobList[i].punishment );
}else
jobList[i].arrive++;
}
}
}
for(int i=head;i<jobList.size();i++){
if( (!jobList[i].isExecuted)&&
jobList[i].deadline<=timeLineF )
income-=( (timeLineF-jobList[i].deadline)*jobList[i].punishment );
}
return income;
}
int main(){
int cpu,memory,timelineF;
int no=1;
int nJobs;
while(cin>>timelineF){
if(timelineF==0)
break;
if(no!=1)
cout<<endl;
cin>>cpu>>memory>>nJobs;
vector<Job> jobList(nJobs);
for(int i=0;i<nJobs;i++){
Job job;
cin>>job.cpu>>job.memory>>job.arrive>>job.deadline;
cin>>job.reward>>job.bonus>>job.punishment;
jobList[i]=job;
}
int income=computeIncome(jobList,cpu,memory,timelineF);
cout<<"Case "<<no<<":"<<income<<endl;
no++;
}
}