说好的ALS呢?
时间限制: 1000 ms 内存限制: 65536 kb
总通过人数: 130 总提交人数: 145
题目描述
每一个手办都是有灵魂的,下面这个高达手办,帅到爆炸有木有O-o。然而要制作这样一件神器却要费不少功夫。假设现在某厂商引进了制作的整套流水车间,决定量产拯救世界。此车间有n条流水线,每条流水线线有m个装配站,编号都为1-m,每条工作线的第i个装配站都执行相同的功能。拼装一个手办要经过m个装配站才能加工完成,经过第i条工作线的第j个装配站要花费p[i][j]的时间,从第i个工作线移动到第j个工作线要花费t[i][j]的时间,请问制造一个高达最少时间是多少?
输入
多组测试数据
对于每一组测试数据,第一行两个整数输入 N,M(100>=N,M>0),分别代表N条工作线和每条线有M个装配站。
接下来N行每行M个数( N*M 的矩阵,第i行第j个数代表描述中的p[i][j] ),0<权值<=100。
接下来N行每行N个数( N*N的矩阵,第i行第j个数代表描述中的t[i][j] ),0<权值<=100。
输出
对于每组数据,输出一行,a+b的值
输入样例
3 3
10 1 10
8 5 10
10 10 2
0 5 2
1 0 5
1 1 0
输出样例
14
解析:
流水线调度问题。
用T[i][j]表示第i条流水线到第j个装配站的最短时间。假设装配到了任意(第k条)流水线的第n站,且从第一站到n-1站都是最短时间完成的,那么从n-1到n的最短时间为min(T[i][n-1]+p[i][n]+t[i][k]),其中i=1到n。
所以状态转移方程为:
or(int station=2; station<=m; station++)
for(int endLine = 1; endLine<=n; endLine++)
for(int startLine=1; startLine<=n; startLine++)
T[endLine][station] = min(T[endLine][station], T[startLine][station-1]+p[endLine][station] + t[startLine][endLine]);
最后遍历T[i][n]记录最小时间即为答案。
代码:
#include<cstdio>
#include<algorithm>
#define INF 0x3f3f3f3f
#define maxn 107
#define LL long long
using namespace std;
int n,m;
int p[maxn][maxn],t[maxn][maxn],T[maxn][maxn];
int Floyd()
{
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
T[i][j] = INF;
}
}
for(int i = 1;i <= n;i++)
{
T[i][1] = p[i][1];
}
for(int i = 2;i <= m;i++)
{
for(int j = 1;j <= n;j++)
{
for(int k = 1;k <= n;k++)
{
T[j][i] = min(T[j][i],T[k][i-1]+p[j][i]+t[k][j]);
}
}
}
int ans = INF;
for(int i = 1;i <= n;i++)
{
ans = min(ans,T[i][m]);
}
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= m;j++)
{
scanf("%d",&p[i][j]);
}
}
for(int i = 1;i <= n;i++)
{
for(int j = 1;j <= n;j++)
{
scanf("%d",&t[i][j]);
}
}
printf("%d\n",Floyd());
}
}