您的位置:首页 > 其它

n流水线m装配站调度问题

2015-10-30 12:43 369 查看
题目:http://biancheng.love/contest/6/problem/F/index

解题思路:

首先需要明白的一点就是由于在同一个流水线的各个装配站之间进行转移是不需要消耗时间的,故最终经过装配站的顺序不影响最终结果。也就是说无论以什么样的编号顺序去经过各装配站,最终得到的最小时间都是一样的。所以我们可以任选一个装配站编号顺序去访问,这里不妨就取编号为从1到m,即按编号1到n的顺序去经过各装配站,但每次所在的流水线是不定的。也就是说我们只需找出一个流水线序列,使得最终花费时间最少即可。

方法:动态规划

我们定义状态A[i][j]表示当前位于i流水线的第j个装配站所花费的最小时间。则A[i][j]可以由A[k][j-1]决定(k=1,2,3……n),而与A[k][j-1]是怎样得到的没有关系,即所谓的满足无后效性。而若要得到A[i][j]的最小值,必然应使A[k]j-1最小,即满足最优子结构性质。满足了这两个条件就可以应用动态规划的方法来解决了。不难得到以下的状态转移方程:

**A[i][j]=min{ A[k][j-1]+t[k][i] }+p[i][j] (k=1,2,3……n)

A[i][1]=p[i][1]**

含义:按照我们规定的顺序,要想到达编号为j的装配站,需要先经过编号为j-1的装配站,则到达装配站j所需最小时间即为所有到达j-1装配站的时间再加上流水线的转换时间中的最小值。

有了状态转移方程问题就很简单了。

#include <bits/stdc++.h>
using namespace std;

const int maxn=101;
int p[maxn][maxn];
int t[maxn][maxn];
int A[maxn][maxn];      //status
int n,m;

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);
for(int i=1;i<=n;i++)
A[i][1]=p[i][1];
for(int j=2;j<=m;j++)
for(int i=1;i<=n;i++)
{
int tmp=INT_MAX;
for(int k=1;k<=n;k++)
if(A[k][j-1]+t[k][i]<tmp)
tmp=A[k][j-1]+t[k][i];
A[i][j]=tmp+p[i][j];
}
int ans=INT_MAX;
for(int i=1;i<=n;i++)
if(A[i][m]<ans)
ans=A[i][m];
//for(int i=2;i<=n;i++)
//  printf("%d ",A[i][m]);
printf("%d\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  解题报告