P1065作业调度方法

        这个题目最重点的地方我认为在于对数据的信息做存储,为什么这么说呢,在输入格式中我们会发现要素尤其之多,存储大概到达了6个部分,并且相互之间还存在关系,一般对于这种分开存储的话就很容易断开这些要素之间的关系,这个时候我们就可以想到结构体,以及二维数组来帮助我们化简这个问题。

int m,n;
int list[501];//工件加工顺序列表 
struct Information{
	int id;
	int cost;
}a[21][21];//[工件][工序]={机器ID,加工时间}; 
int mac[21][100001]={0};//机器事件记录表:mac[机器][加工时间]; 
int step[21]={0};//记录每个工件当前进行到第几步 
int last_time[21]={0};//记录每个工件最后完成的时间 
int ans=0;//最终总的完成时间 

        二维数组的存储方式,如果你理解了背包问题,那么你就可以很轻松的理解这个部分,然后这里面比较重要的就是mac数组,mac数组的话行元素代表机器,列元素代表加工的每个单位时间,对这个单位时间进行判断,可以得知这个时间是否有工件的工序在占用机器。

int main()
{
	cin>>m>>n;
	for(int i=1;i<=m*n;i++)
	{
		cin>>list[i];
	}
	for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            scanf("%d", &a[i][j].id);
        }
    }
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>a[i][j].cost;
		}
	}
	for(int i=1;i<=m*n;i++)
	{
		int now=list[i];//当前要加工的工件 
		step[now]++;//该工件进入下一步工序 
		int id=a[now][step[now]].id;//当前的工序的机器号 
		int cost=a[now][step[now]].cost;//当前工序花费的时间
		//在机器id上寻找cost个空闲的时间 
		int s=0;//连续空闲时间的计数器 
		for(int j=last_time[now]+1;;j++)
		{
			if(mac[id][j]==0)//第几个机器的第几个时间为0 
			{
				s++;
			}
			else{
				s=0;
			}
			if(s==cost)
			{
				for(int k=j-cost+1;k<=j;k++)
				{
					mac[id][k]=1;
				}
				if(j>ans) ans=j;
				last_time[now]=j;
				break;
			}
		}
	}
	cout<<ans;
	return 0;
} 

这里面输入的部分也是按照题目意思,一步一步输入的,就不做过多讲解

现在这段代码里面最核心的部分就是for循环,两层for循环,第一层表示处理到了某一个工件的某一个工序,第二层循环表示的就是为这个工序寻找机器时间来完成工作。那么由于有mac数组,并且要按照一定顺序来进行加工,就可以做是在一条直线上找到合适的长度,这样的话就将所有时间压缩到一个最有效的状态,并且每一个机器都是一条完全崭新的直线,每个机器都互相不阻碍,每个工件也是按照顺序执行的,虽有工件工序之间也不会造成冲突。

再放一个完整的代码。

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int m,n;
int list[501];//工件加工顺序列表 
struct Information{
	int id;
	int cost;
}a[21][21];//[工件][工序]={机器ID,加工时间}; 
int mac[21][100001]={0};//机器事件记录表:mac[机器][加工时间]; 
int step[21]={0};//记录每个工件当前进行到第几步 
int last_time[21]={0};//记录每个工件最后完成的时间 
int ans=0;//最终总的完成时间 
int main()
{
	cin>>m>>n;
	for(int i=1;i<=m*n;i++)
	{
		cin>>list[i];
	}
	for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            scanf("%d", &a[i][j].id);
        }
    }
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>a[i][j].cost;
		}
	}
	for(int i=1;i<=m*n;i++)
	{
		int now=list[i];//当前要加工的工件 
		step[now]++;//该工件进入下一步工序 
		int id=a[now][step[now]].id;//当前的工序的机器号 
		int cost=a[now][step[now]].cost;//当前工序花费的时间
		//在机器id上寻找cost个空闲的时间 
		int s=0;//连续空闲时间的计数器 
		for(int j=last_time[now]+1;;j++)
		{
			if(mac[id][j]==0)//第几个机器的第几个时间为0 
			{
				s++;
			}
			else{
				s=0;
			}
			if(s==cost)
			{
				for(int k=j-cost+1;k<=j;k++)
				{
					mac[id][k]=1;
				}
				if(j>ans) ans=j;
				last_time[now]=j;
				break;
			}
		}
	}
	cout<<ans;
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值