装配线调度
一:题意
生产汽车。一个汽车底盘在进入每一条装配线后,在一些装配站中会在底盘安装部件,然后完成的汽车在装配线的末端离开。每条装配线上有n个装配站,将装配线i(i为1或2)的第j个装配站表示为Si,j。装配线1的第j个站与装配线2的第j个站执行同样的功能。
每个站所需时间不同。我们把在装配站Si,j所需装配时间记为ai,j。一个汽车底盘进入其中一条装配线,然后从一站进行到下一站。底盘进入装配线i所需时间为ei,装配完离开装配线i所需时间为xi。
偶尔来了一个特别急的订单。对这些加急的订单,底盘依然依次经过n个装配站,但是工厂可将部分完成的汽车在任何装配站上从一条装配线移到另一条装配线上。把已经通过装配站Si,j的一个底盘从装配线i移走所需时间为ti,j,其中i=1,2,而j=1,2,...n-1(因为在第n个装配站后,装配已完成)。
你需要编一个程序,来确定在装配线1中选哪些站及在装配线2中选哪些站,以使汽车通过工厂的时间最少。
输入格式
第一行输入一个数字n,每条装配线上有n个装配站。
第二、三行各有n+2个数字,表示两条装配线进入、经过每个站点、离开的时间。
第四、五行各有n-1个数字,表示两条装配线之间切换的时间。
二:分析(计算过程)
关键词:i[1或2](两条装配线),n(n个装配站),s[i][j](任意一个装配线),a[i][j](在s[i][j]上的装配时间),t[i][j](在s[i][j]上换线的时间),e[i](i线入线的时间),x[i](i线出线的时间)
根据对dp的理解,我们看出本题求的是最小值(出线最短时间),因dp的无后效性,可以设两个dp[i][j],用来存s[i][j]前的最优解。dp数组在入线是无法选择换线的,所以需要赋一个初值,也就是入线时间+初站时间(e[i]+a[i][0])。赋完初值后就可以开始“状态转移方程”。
因为本题求最小值,所以用min函数比较出更优解,以旧的dp数组为基础,建立新的,阶段性的最优解,由此递进。状态转移方程于是为:选择是否换线中更优值的语句。
状态转移方程后,我们得出两个dp最优值,将他们手动出线后(+x[i]),再通过min来求出最后的最优解。于是 本题完结!
AC代码如下:
#include<bits/stdc++.h>
using namespace std;
long long n,e[3],x[3],a[3][1000001],t[3][1000001];
long long dp[3][1000001];
int main()
{
cin>>n;
for(int i=0;i<2;i++)
{
cin>>e[i];
for(int j=1;j<=n;j++)
cin>>a[i][j];
cin>>x[i];
}
for(int i=0;i<2;i++)
for(int j=1;j<=n-1;j++)
cin>>t[i][j];
dp[0][1]=e[0]+a[0][1];
dp[1][1]=e[1]+a[1][1];
for(int j=2;j<=n;j++)
{
dp[0][j]=min(dp[0][j-1],dp[1][j-1]+t[1][j-1])+a[0][j];
dp[1][j]=min(dp[1][j-1],dp[0][j-1]+t[0][j-1])+a[1][j];
}
cout<<min(dp[0][n]+x[0],dp[1][n]+x[1]);
return 0;
}
创作不易,望多加支持。