大家好,我是一只学弱狗,记录学习的点点滴滴!
优质文章
优质专栏
题目描述
有n项任务,任务i的加工时间为ti,ti为正整数,i=1,2,…n,用两台相同的机器加工,从0时刻开始计时,完成时间是后停止加工机器的停机时间,问如何把这些任务分配到两台机器上,使得完成时间达到做小?
分析
这个题呢,不知道大家看完什么感受,我觉的是挺不好搞的,但是呢,通过老师的指点,我猛然间就会做了,现在我也讲给你听:首先我们可以设解是取值只能是0或1的向量<x1,x2,…,xn>,当为0时,表示任务i分配到第一台机器,当为1时,表示任务i分配给第二台机器,设机器1的加工时间<=机器2的加工时间,令T=t1+t2+…+tn,D=T/2下取整,机器1的加工时间不超过D,且达到最大,这样就能保证机器2的加工时间达到最小,从而使得总时间达到最小。所以我们只需分析当时间D内,使得任务的总时间达到最大,类比背包问题,D可以看做是背包的容量,每个任务的加工时间可看做是商品的价值和重量,就可以求出机器1加工时间的最大值。
#include <iostream>
using namespace std;
int main(){
int n,T=0;
freopen("双机调度问题.txt","r",stdin);
cin>>n;
int *data = new int[n];
for(int i=0;i<n;i++) {
cin>>data[i];
T+=data[i];
}
int D = T/2;
//背包问题:背包容量是D,各个任务看做商品,加工时间看做质量和重量
//用滚动数组来求解
int **map = new int*[2];
for(int i=0;i<2;i++){
map[i] = new int[D+1];
}
for(int i=0;i<2;i++)
for(int j=0;j<=D;j++)
map[i][j]=0;
for(int i=1;i<=n;i++){
for(int j=0;j<=D;j++){
if(data[i-1]<=j){
map[i%2][j]=max(map[(i+1)%2][j],map[(i+1)%2][j-data[i-1]]+data[i-1]);
}else{
map[i%2][j]=map[(i+1)%2][j];
}
}
}
cout<<max(map[n%2][D],T-map[n%2][D])<<endl;
return 0;
}
具体方案
#include <iostream>
using namespace std;
int main(){
int n,T=0;
freopen("双机调度问题.txt","r",stdin);
cin>>n;
int *data = new int[n];
for(int i=0;i<n;i++) {
cin>>data[i];
T+=data[i];
}
int D = T/2;
//背包问题:背包容量是D,各个任务看做商品,加工时间看做质量和重量
//用滚动数组来求解
int **map = new int*[n+1];
for(int i=0;i<n+1;i++){
map[i] = new int[D+1];
}
for(int i=0;i<n+1;i++)
for(int j=0;j<=D;j++)
map[i][j]=0;
int **rect = new int*[n+1];//追踪数组
for(int i=0;i<n+1;i++){
rect[i] = new int[D+1];
}
for(int i=0;i<n+1;i++)
for(int j=0;j<=D;j++)
rect[i][j]=0;
for(int i=1;i<=n;i++){
for(int j=0;j<=D;j++){
if(data[i-1]<=j){
int temp1 = map[i-1][j];
int temp2 = map[i-1][j-data[i-1]]+data[i-1];
if(temp2>=temp1){
rect[i][j]=1;
map[i][j] = temp2;
}else{
rect[i][j]=0;
map[i][j] = temp1;
}
}else{
rect[i][j]=0;
map[i][j]=map[i-1][j];
}
}
}
for(int i=0;i<n+1;i++){
for(int j=0;j<=D;j++)
cout<<rect[i][j]<<" ";
cout<<endl;
}
cout<<"-----------------------"<<endl;
for(int i=0;i<n+1;i++){
for(int j=0;j<=D;j++)
cout<<map[i][j]<<" ";
cout<<endl;
}
int *recode = new int[n];
for(int i=0;i<n;i++)
recode[i] = 1;
//求解具体方案
int x=n,y=D;
while(x>=0 && y>=0){
if(rect[x][y]==1){
recode[x-1]=0;
y-=data[x-1];
}
x--;
}
for(int i=0;i<n;i++){
if(recode[i]==0){
cout<<"机器1:"<<i+1<<endl;
}else{
cout<<"机器2:"<<i+1<<endl;
}
}
for(int i=0;i<n+1;i++){
delete[] map[i];
delete[] rect[i];
}
delete[] map;
delete[] rect;
return 0;
}