一、题意
题目描述
Colonel公司在有两条装配线的工厂里生产汽车。一个汽车底盘在进入每一条装配线后,在一些装配站中会在底盘安装部件,然后完成的汽车在装配线的末端离开。每条装配线上有n个装配站,编号分别为j=1,2,...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个数字,表示两条装配线之间切换的时间。
输出格式
输出最小时间
二、算法分析
关键词
n(n个装配站)
i(i号装配线 i为1或2)
j(第j个装配站)
a[i][j](i号线j装配站所需装配时间)
e[i](i号线的进线时间)
x[i](i号线的出线时间)
t[i][j](在i号线j装配站上换线的时间)
所求的为汽车通过工厂的最短时间
因dp的擅长解决最值问题,这道题求的是最短时间,所以我们可以用dp解决
接着我们就可以来分析一下dp六要素
dp六要素
1. 状态
i条线,j号站点,最小时间(所求)
dp的值受两个对象影响,设二维数组 dp[i][j]
2.阶段
1—>2—>3—>4—>5—>......—>n-1—>n
3.决策
1号线i+1站或2号线i+1站
4.状态转移方程
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]
5.初始值(边界)
在第一站时无法换线,所以我们需要为dp设置一个初始值
即i号线的进站时间加上第一站的装配时间
dp[0][1]=e[0]+a[0][1];
dp[1][1]=e[1]+a[1][1];
6.目标值(答案)
min(dp[0][n]+x[0],dp[1][n]+x[1])
三、代码实现
#include<bits/stdc++.h>
using namespace std;
long long e[5],x[5],n,a[5][1000001],t[5][1000001],dp[5][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])<<endl;//输出
return 0;
}