问题描述:
用2台处理机A和B处理n个作业。设第i个作业交给机器A处理时需要时间ai,若由机器B来处理,则需要时间bi。由于各作业的特点和机器的性能关系,很可能对于某些i,有ai>bi,而对于某些j,j≠i,有aj>bj。既不能将一个作业分开由2台机器处理,也没有一台机器能同时处理2个作业。设计一个动态规划算法,使得这2台机器处理完这n个作业的时间最短(从任何一台机器开工到最后一台机器停工的总时间)。研究一个实例:
(a1,a2,a3,a4,a5,a6)=(2,5,7,10,5,2);(b1,b2,b3,b4,b5,b6)=(3,8,4,11,3,4)。
对于给定的2台处理机A和B处理n个作业,找出一个最优调度方案,使2台机器处理完这n个作业的时间最短。
思路:
首先要注意每个作业仅需要处理一次就行,不需要被机器A和B各处理一遍
采用动态规划;
定义F[i][j]为:表示完成i个作业且机器A花费j时间的条件下机器B所花费时间的最小值,那么F[i][j] = min{F[i – 1][j] + b[i], F[i – 1][j – a[i]]}。解释一下:
假设前i – 1件已经被处理了,那么第 i 件作业由谁来处理呢?
可以分两种情况:
1:由机器A处理i,则机器B的时间为 F[i – 1][j – a[i]];
2:由机器B处理i,则机器B的时间为 F[i – 1][j] + b[i];
特殊情况:如果j < a[i],则不可能由机器A来完成,此时F[i][j] = F[i – 1][j] + b[i];
最终F[i][j] 选择 1 和 2 中较小的一个,即F[i][j] = min{F[i – 1][j] + b[i], F[i – 1][j – a[i]]}。
代码:
#include <bits/stdc++.h>
using namespace std;
int n;
int time_a = 0; //最终的时间一定小于time_a, 即 min_t < time_a
int min_t = 0x3f3f3f;
int a[1024];
int b[1024];
int F[1024][1024];
void inPut()
{
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
{
scanf("%d", &a[i]);
time_a += a[i];
}
for(int i = 1; i <= n; ++i)
scanf("%d", &b[i]);
}
void solve()
{
memset(F, 0, sizeof(F));
for(int i = 1; i <= n; ++i)
{
for(int j = 0; j <= time_a; ++j)
{
if(j > a[i])
{
F[i][j] = min(F[i - 1][j - a[i]], F[i - 1][j] + b[i]);
}
else
{
F[i][j] = F[i - 1][j] + b[i];
}
}
}
int temp;
for(int i = 0; i <= time_a; ++i)
{
temp = max(F[n][i], i);
if(min_t > temp)
min_t = temp;
}
}
int main()
{
inPut();
solve();
printf("%d\n", min_t);
}
代码2:(路径压缩)
#include <bits/stdc++.h>
using namespace std;
int n;
int *a;
int *b;
int *t;
int sa = 0;
int result = 0x3f3f3f;
void outPut()
{
int temp;
for(int i = 0; i <= sa; ++i)
{
temp = i > t[i] ? i : t[i];
if(result > temp)
result = temp;
}
printf("the result is %d\n",result);
delete []a;
delete []b;
delete []t;
}
void solve()
{
t = new int[sa + 1];
memset(t, 0, sizeof(t)); //t初始化为0
for(int k = 0; k < n; ++k)
{
for(int i = sa; i >= 0; --i)
{
if(i >= a[k])
{
t[i] = min(t[i] + b[k], t[i - a[k]]);
}
else
{
t[i] = t[i] + b[k];
}
}
}
}
void inPut()
{
scanf("%d", &n);
a = new int[n];
b = new int[n];
for(int i = 0; i < n; ++i)
{
scanf("%d", &a[i]);
sa += a[i];
}
for(int i = 0; i < n; ++i)
scanf("%d", &b[i]);
}
int main()
{
inPut();
solve();
outPut();
}
参考:https://blog.csdn.net/qq_26658823/article/details/78298957