一家汽车厂有两条装配线,每条装配线有 n 个工位。工位用S i,j表示,其中i 为1 或2,表示工位所在的装配线,j 表示工位编号。每个站所用的时间由 a i,j 表示。每个工作站都专门从事某种工作,例如发动机装配、车身装配、喷漆等。所以,一个汽车底盘在出厂前必须依次通过n个工位。两条装配线的平行工位执行相同的任务。它经过S i,j站后,将继续到S i,j+1站,除非它决定换乘另一条线路。继续在同一条线路上不会产生额外费用,但从第 j – 1 站的第 i 线转移到另一条线路上的第 j 站需要时间 t i,j 。每条装配线需要一个进入时间 e i和退出时间 x i ,这两条线可能不同。给出一个算法来计算构建汽车底盘所需的最短时间。
下图清楚地展示了问题:
可以从问题陈述中提取以下信息以使其更简单:
- 两条装配线,1 和 2,每条装配线从 1 到 n。
- 一个汽车底盘必须按顺序通过从1到n的所有工位(在两条装配线中的任何一条中)。即如果它们不在一个移动距离内,它就不能从站 i 跳到站 j。
- 汽车底盘可以在同一条线上向前移动一个站,也可以在另一条线对角移动一个站。从线路 i 移动到站 j 会产生额外的成本 ti, j。在同一条线上移动不会产生成本。
- 在 i 线上的 j 站所用的时间是 a i, j 。
- S i, j代表第 i 线上的站 j。
将问题分解为更小的子问题:
如果第 (i-1) 个阶乘已知,我们可以很容易地找到第 i 个阶乘。我们可以在这里应用类似的基础吗?
如果已知底盘离开站点S i, j-1的最短时间,则可以通过组合a i, j和t i, j快速计算出离开站点S i, j所需的最短时间。
T1(j)表示汽车底盘离开装配线 1 上的站 j 所用的最短时间。
T2(j)表示汽车底盘离开装配线 2 上的站 j 所用的最短时间。
基本情况:
进入时间e i只有在汽车底盘进入汽车工厂时才会出现。
离开 1 号线第一个站所用的时间为:
T1(1) = 1号线进入时间+ S 1,1站时间
T1(1) = e 1 + a 1,1
类似地,离开 2 号线第一个站所用的时间为:
T2(1) = e 2 + a 2,1
递归关系:
如果我们查看问题陈述,它很快可以归结为以下观察结果:
S 1,j站的汽车底盘可以来自S 1, j-1站或S 2, j-1站。
案例#1:它的前一站是S 1, j-1
离开站点 S 1,j的最短时间由下式给出:
T1(j) = 离开站点 S 1, j-1 所需的最短时间 + 在站点 S 1, j 中花费的时间
T1(j) = T1(j-1) + a 1, j
案例#2:它的前一站是 S 2, j-1
离开站点 S1 的最短时间 j 由下式给出:
T1(j) = 离开站点 S 2, j-1所需的最短时间 + 更改装配线产生的额外成本 + 在站点 S 1, j花费的时间
T1(j) = T2(j-1) + t 2, j + a 1, j
最短时间 T1(j) 由在 #1 和 #2 情况下获得的两者中的最小值给出。
T1(j) = min((T1(j-1) + a 1, j ), (T2(j-1) + t 2, j + a 1, j ))
类似地,到达站点 S2 的最短时间 j 由下式给出:
T2(j) = min((T2(j-1) + a 2, j ), (T1(j-1) + t 1, j + a 2, j ))
汽车底盘出厂所需的总最短时间由下式给出:
Tmin = min(离开S i,n站所用时间+离开汽车厂所用时间)
Tmin = min(T1(n) + x 1 , T2(n) + x 2 )
为什么要动态规划?
上述递归表现出重叠的子问题。有两种方法可以到达 S 1, j站:
- 从站 S 1, j-1
- 从站 S 2, j-1
因此,要找到离开站点 S 1的最短时间,必须计算离开前两个站点的最短时间j (如上述递归中所述)。
同样,到达站点 S 2, j有两种方式:
- 从站 S 2, j-1
- 从站 S 1, j-1
请注意,离开站点 S 1, j-1和 S 2, j-1的最短时间已经计算完毕。
因此,我们需要两个表来存储为装配线中每个工位计算的部分结果。表格将以自下而上的方式填充。
笔记:
在这篇文章中,使用“离开”一词代替“到达”以避免混淆。由于汽车底盘必须在每个站点停留固定的时间,所以离开这个词更合适。
执行:
C++
// A C++ program to find minimum possible
// time by the car chassis to complete
#include
using namespace std;
#define NUM_LINE 2
#define NUM_STATION 4
// Utility function to find a minimum of two numbers
int min(int a, int b)
{
return a < b ? a : b;
}
int carAssembly(int a[][NUM_STATION],
int t[][NUM_STATION],
int *e, int *x)
{
int T1[NUM_STATION], T2[NUM_STATION], i;
// time taken to leave first station in line 1
T1[0] = e[0] + a[0][0];
// time taken to leave first station in line 2
T2[0] = e[1] + a[1][0];
// Fill tables T1[] and T2[] using the
// above given recursive relations
for (i = 1; i < NUM_STATION; ++i)
{
T1[i] = min(T1[i - 1] + a[0][i],
T2[i - 1] + t[1][i] + a[0][i]);
T2[i] = min(T2[i - 1] + a[1][i],
T1[i - 1] + t[0][i] + a[1][i]);
}
// Consider exit times and retutn minimum
return min(T1[NUM_STATION - 1] + x[0],
T2[NUM_STATION - 1] + x[1]);
}
// Driver Code
int main()
{
int a[][NUM_STATION] = {{4, 5, 3, 2},
{2, 10, 1, 4}};
int t[][NUM_STATION] = {{0, 7, 4, 5},
{0, 9, 2, 8}};
int e[] = {10, 12}, x[] = {18, 7};
cout << carAssembly(a, t, e, x);
return 0;
}
// This is code is contributed by rathbhupendra
C
// A C program to find minimum possible time by the car chassis to complete
#include
#define NUM_LINE 2
#define NUM_STATION 4
// Utility function to find minimum of two numbers
int min(int a, int b) { return a < b ? a : b; }
int carAssembly(int a[][NUM_STATION], int t[][NUM_STATION], int *e, int *x)
{
int T1[NUM_STATION], T2[NUM_STATION], i;
T1[0] = e[0] + a[0][0]; // time taken to leave first station in line 1
T2[0] = e[1] + a[1][0]; // time taken to leave first station in line 2
// Fill tables T1[] and T2[] using the above given recursive relations
for (i = 1; i < NUM_STATION; ++i)
{
T1[i] = min(T1[i-1] + a[0][i], T2[i-1] + t[1][i] + a[0][i]);
T2[i] = min(T2[i-1] + a[1][i], T1[i-1] + t[0][i] + a[1][i]);
}
// Consider exit times and retutn minimum
return min(T1[NUM_STATION-1] + x[0], T2[NUM_STATION-1] + x[1]);
}
int main()
{
int a[][NUM_STATION] = {{4, 5, 3, 2},
{2, 10, 1, 4}};
int t[][NUM_STATION] = {{0, 7, 4, 5},
{0, 9, 2, 8}};
int e[] = {10, 12}, x[] = {18, 7};
printf("%d", carAssembly(a, t, e, x));
return 0;
}
Java
// A java program to find minimum possible
// time by the car chassis to complete
import java.io.*;
class GFG
{
static int NUM_LINE = 2;
static int NUM_STATION = 4;
// Utility function to find minimum of two numbers
static int min(int a, int b)
{
return a < b ? a : b;
}
static int carAssembly(int a[][], int t[][], int e[], int x[])
{
int T1[]= new int [NUM_STATION];
int T2[] =new int[NUM_STATION] ;
int i;
// time taken to leave first station in line 1
T1[0] = e[0] + a[0][0];
// time taken to leave first station in line 2
T2[0] = e[1] + a[1][0];
// Fill tables T1[] and T2[] using
// the above given recursive relations
for (i = 1; i < NUM_STATION; ++i)
{
T1[i] = min(T1[i - 1] + a[0][i],
T2[i - 1] + t[1][i] + a[0][i]);
T2[i] = min(T2[i - 1] + a[1][i],
T1[i - 1] + t[0][i] + a[1][i]);
}
// Consider exit times and retutn minimum
return min(T1[NUM_STATION-1] + x[0],
T2[NUM_STATION-1] + x[1]);
}
// Driver code
public static void main (String[] args)
{
int a[][] = {{4, 5, 3, 2},
{2, 10, 1, 4}};
int t[][] = {{0, 7, 4, 5},
{0, 9, 2, 8}};
int e[] = {10, 12}, x[] = {18, 7};
System.out.println(carAssembly(a, t, e, x));
}
}
// This code is contributed by vt_m
Python3
# Python program to find minimum possible
# time by the car chassis to complete
def carAssembly (a, t, e, x):
NUM_STATION = len(a[0])
T1 = [0 for i in range(NUM_STATION)]
T2 = [0 for i in range(NUM_STATION)]
T1[0] = e[0] + a[0][0] # time taken to leave
# first station in line 1
T2[0] = e[1] + a[1][0] # time taken to leave
# first station in line 2
# Fill tables T1[] and T2[] using
# above given recursive relations
for i in range(1, NUM_STATION):
T1[i] = min(T1[i-1] + a[0][i],
T2[i-1] + t[1][i] + a[0][i])
T2[i] = min(T2[i-1] + a[1][i],
T1[i-1] + t[0][i] + a[1][i] )
# consider exit times and return minimum
return min(T1[NUM_STATION - 1] + x[0],
T2[NUM_STATION - 1] + x[1])
a = [[4, 5, 3, 2],
[2, 10, 1, 4]]
t = [[0, 7, 4, 5],
[0, 9, 2, 8]]
e = [10, 12]
x = [18, 7]
print(carAssembly(a, t, e, x))
# This code is contributed by Soumen Ghosh
C#
// A C# program to find minimum possible
// time by the car chassis to complete
using System;
class GFG {
static int NUM_STATION = 4;
// Utility function to find minimum
// of two numbers
static int min(int a, int b)
{
return a < b ? a : b;
}
static int carAssembly(int [,]a, int [,]t,
int []e, int []x)
{
int []T1= new int [NUM_STATION];
int []T2 =new int[NUM_STATION] ;
int i;
// time taken to leave first station
// in line 1
T1[0] = e[0] + a[0,0];
// time taken to leave first station
// in line 2
T2[0] = e[1] + a[1,0];
// Fill tables T1[] and T2[] using
// the above given recursive relations
for (i = 1; i < NUM_STATION; ++i)
{
T1[i] = min(T1[i - 1] + a[0,i],
T2[i - 1] + t[1,i] + a[0,i]);
T2[i] = min(T2[i - 1] + a[1,i],
T1[i - 1] + t[0,i] + a[1,i]);
}
// Consider exit times and retutn
// minimum
return min(T1[NUM_STATION-1] + x[0],
T2[NUM_STATION-1] + x[1]);
}
// Driver code
public static void Main ()
{
int [,]a = { {4, 5, 3, 2},
{2, 10, 1, 4} };
int [,]t = { {0, 7, 4, 5},
{0, 9, 2, 8} };
int []e = {10, 12};
int []x = {18, 7};
Console.Write(carAssembly(a, t, e, x));
}
}
// This code is contributed by nitin mittal.
PHP
Javascript
C++
// A space optimized solution for
// assembly line scheduling
#include
using namespace std;
int carAssembly(int a[][4],
int t[][4],
int *e, int *x)
{
int first, second, i;
// Time taken to leave first
// station in line 1
first = e[0] + a[0][0];
// Time taken to leave first
// station in line 2
second = e[1] + a[1][0];
// Fill tables T1[] and T2[] using the
// above given recursive relations
for(i = 1; i < 4; ++i)
{
int up = min(first + a[0][i],
second + t[1][i] +
a[0][i]);
int down = min(second + a[1][i],
first + t[0][i] +
a[1][i]);
first = up;
second = down;
}
// Consider exit times and
// return minimum
return min(first + x[0],
second + x[1]);
}
// Driver Code
int main()
{
int a[][4] = { { 4, 5, 3, 2 },
{ 2, 10, 1, 4 } };
int t[][4] = { { 0, 7, 4, 5 },
{ 0, 9, 2, 8 } };
int e[] = { 10, 12 }, x[] = { 18, 7 };
cout << carAssembly(a, t, e, x);
return 0;
}
// This code is contributed by chitrasingla2001
Java
// A space optimized solution for assembly line scheduling
public class AssemblyLine {
public static void main(String[] args) {
int a[][] = {{4, 5, 3, 2},
{2, 10, 1, 4}};
int t[][] = {{0, 7, 4, 5},
{0, 9, 2, 8}};
int e[] = {10, 12}, x[] = {18, 7};
System.out.println(carAssembleTime(a, t, e, x));
}
public static int carAssembleTime(int a[][], int t[][],
int e[], int x[]) {
int n = a[0].length;
// time taken to leave first station in line 1
int first = e[0] + a[0][0];
// time taken to leave first station in line 2
int second = e[1] + a[1][0];
for (int i = 1; i < n; i++) {
int up = Math.min(first + a[0][i],
second + t[1][i] + a[0][i]),
down = Math.min(second + a[1][i],
first + t[0][i] + a[1][i]);
first = up;
second = down;
}
first += x[0];
second += x[1];
return Math.min(first, second);
}
}
Python3
# A space optimized solution for assembly
# line scheduling in Python3
def carAssembleTime(a, t, e, x):
n = len(a[0])
# Time taken to leave first station
# in line 1
first = e[0] + a[0][0]
# Time taken to leave first station
# in line 2
second = e[1] + a[1][0]
for i in range(1, n):
up = min(first + a[0][i],
second + t[1][i] + a[0][i])
down = min(second + a[1][i],
first + t[0][i] + a[1][i])
first, second = up, down
first += x[0]
second += x[1]
return min(first, second)
# Driver Code
a = [ [ 4, 5, 3, 2 ], [ 2, 10, 1, 4 ] ]
t = [ [ 0, 7, 4, 5 ], [ 0, 9, 2, 8 ] ]
e = [ 10, 12 ]
x = [ 18, 7 ]
print(carAssembleTime(a, t, e, x))
# This code is contributed by Prateek Gupta
C#
// A space optimized solution for
// assembly line scheduling
using System;
class GFG{
static int carAssembleTime(int[,] a, int[,] t,
int[] e, int[] x)
{
int n = a.GetLength(1);
// Time taken to leave first station in line 1
int first = e[0] + a[0, 0];
// Time taken to leave first station in line 2
int second = e[1] + a[1, 0];
for(int i = 1; i < n; i++)
{
int up = Math.Min(first + a[0, i],
second + t[1, i] + a[0, i]),
down = Math.Min(second + a[1, i],
first + t[0, i] + a[1, i]);
first = up;
second = down;
}
first += x[0];
second += x[1];
return Math.Min(first, second);
}
// Driver Code
static void Main()
{
int[,] a = { { 4, 5, 3, 2 },
{ 2, 10, 1, 4 } };
int[,] t = { { 0, 7, 4, 5 },
{ 0, 9, 2, 8 } };
int[] e = { 10, 12 }, x = { 18, 7 };
Console.WriteLine(carAssembleTime(a, t, e, x));
}
}
// This code is contributed by divyeshrabadiya07
35
粗线显示给定输入值的汽车底盘覆盖的路径。我们只需要辅助数组中的最后两个值。因此,我们可以使用两个变量,而不是创建两个数组。
C++
// A space optimized solution for
// assembly line scheduling
#include
using namespace std;
int carAssembly(int a[][4],
int t[][4],
int *e, int *x)
{
int first, second, i;
// Time taken to leave first
// station in line 1
first = e[0] + a[0][0];
// Time taken to leave first
// station in line 2
second = e[1] + a[1][0];
// Fill tables T1[] and T2[] using the
// above given recursive relations
for(i = 1; i < 4; ++i)
{
int up = min(first + a[0][i],
second + t[1][i] +
a[0][i]);
int down = min(second + a[1][i],
first + t[0][i] +
a[1][i]);
first = up;
second = down;
}
// Consider exit times and
// return minimum
return min(first + x[0],
second + x[1]);
}
// Driver Code
int main()
{
int a[][4] = { { 4, 5, 3, 2 },
{ 2, 10, 1, 4 } };
int t[][4] = { { 0, 7, 4, 5 },
{ 0, 9, 2, 8 } };
int e[] = { 10, 12 }, x[] = { 18, 7 };
cout << carAssembly(a, t, e, x);
return 0;
}
// This code is contributed by chitrasingla2001
Java
// A space optimized solution for assembly line scheduling
public class AssemblyLine {
public static void main(String[] args) {
int a[][] = {{4, 5, 3, 2},
{2, 10, 1, 4}};
int t[][] = {{0, 7, 4, 5},
{0, 9, 2, 8}};
int e[] = {10, 12}, x[] = {18, 7};
System.out.println(carAssembleTime(a, t, e, x));
}
public static int carAssembleTime(int a[][], int t[][],
int e[], int x[]) {
int n = a[0].length;
// time taken to leave first station in line 1
int first = e[0] + a[0][0];
// time taken to leave first station in line 2
int second = e[1] + a[1][0];
for (int i = 1; i < n; i++) {
int up = Math.min(first + a[0][i],
second + t[1][i] + a[0][i]),
down = Math.min(second + a[1][i],
first + t[0][i] + a[1][i]);
first = up;
second = down;
}
first += x[0];
second += x[1];
return Math.min(first, second);
}
}
蟒蛇3
# A space optimized solution for assembly
# line scheduling in Python3
def carAssembleTime(a, t, e, x):
n = len(a[0])
# Time taken to leave first station
# in line 1
first = e[0] + a[0][0]
# Time taken to leave first station
# in line 2
second = e[1] + a[1][0]
for i in range(1, n):
up = min(first + a[0][i],
second + t[1][i] + a[0][i])
down = min(second + a[1][i],
first + t[0][i] + a[1][i])
first, second = up, down
first += x[0]
second += x[1]
return min(first, second)
# Driver Code
a = [ [ 4, 5, 3, 2 ], [ 2, 10, 1, 4 ] ]
t = [ [ 0, 7, 4, 5 ], [ 0, 9, 2, 8 ] ]
e = [ 10, 12 ]
x = [ 18, 7 ]
print(carAssembleTime(a, t, e, x))
# This code is contributed by Prateek Gupta
C#
// A space optimized solution for
// assembly line scheduling
using System;
class GFG{
static int carAssembleTime(int[,] a, int[,] t,
int[] e, int[] x)
{
int n = a.GetLength(1);
// Time taken to leave first station in line 1
int first = e[0] + a[0, 0];
// Time taken to leave first station in line 2
int second = e[1] + a[1, 0];
for(int i = 1; i < n; i++)
{
int up = Math.Min(first + a[0, i],
second + t[1, i] + a[0, i]),
down = Math.Min(second + a[1, i],
first + t[0, i] + a[1, i]);
first = up;
second = down;
}
first += x[0];
second += x[1];
return Math.Min(first, second);
}
// Driver Code
static void Main()
{
int[,] a = { { 4, 5, 3, 2 },
{ 2, 10, 1, 4 } };
int[,] t = { { 0, 7, 4, 5 },
{ 0, 9, 2, 8 } };
int[] e = { 10, 12 }, x = { 18, 7 };
Console.WriteLine(carAssembleTime(a, t, e, x));
}
}
// This code is contributed by divyeshrabadiya07
35
锻炼:
扩展上述算法,打印出工厂汽车底盘所覆盖的路径。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。