#include using namespace std; const int N = 20 + 10; //m<20,n<20,范围是20以内,开大一点防止出错 //题意解析 //https://www.bilibili.com/video/BV14K411J7Hr?from=search&seid=5350204733209198842 //手绘图形进行样例解析说明,让学生们手工绘制帮助理解题意。 //用来记录题目输入的数据信息 int n, m; //m表示机器数,n表示工件数 int seq[N * N]; //为给定的安排顺序。大小为m*n,所以开了一个N*N的数组。是安排顺序的简写形式。 //举个例子: 112332 表示第一个工件第一道工序,第一个工件第二道工序,第二个工件第1个工序.... int p[N][N]; //工件+工序的机器号 int t[N][N]; //工件+工序的执行时长 //下面是程序开发中需要的中间变量 int cnt[N]; //用来存储遍历到了当前工件的第几个工序 //Q:为什么要用数组来存储是第几个工序? //A:因为有多个工件,每一个工件都随时需要知道它现在再次出现的是第几个工序了,需要有地方可以查询到,这里使用了桶排的思想。 int last[N]; //记录每份工件的最后一次加工时间 //Q:为什么要记录最后一次的加工时间? //A:因为每个工件,它的加工顺序是不能反的,也就是规则1,如何才能不违反规则1呢?就是记录下它的最后一次执行时间,然后把下一个工序安排在最后一次执行时间后面就行了。 int res[N][N * N * 100]; //标识每台机器的时间使用情况,第一维:机器,第二维:时间,值:是不是占用了 /** * 功能:检查函数 * @param start 从哪个时间开始 * @param len 需要多长的时间 * @param mac 哪台机器上进行检查 * @return 是不是能放得下去 */ bool check(int start, int len, int mac) { for (int i = start; i < start + len; i++) if (res[mac][i])return false; //在这个范围内,如果有使用的情况,就返回false, 表示放不下去 //全部通过,表示可以放的下去,返回true return true; } int main() { //m机器数,n工件数 //示例数据:2 3,表示2台机器,3个工件 cin >> m >> n; //给定的安排顺序,示例数据:1 1 2 3 3 2,描述第一个物品第一个工序,第一个物品第二个工序,第二个物品第一个工序,第三个物品第一个工序,第三个物品第二个工序,第二个物品第二个工序 for (int i = 1; i <= n * m; i++) cin >> seq[i]; /** 前n行依次表示每个工件的每个工序所使用的机器号,第1个数为第1个工序的机器号,第2个数为第2个工序机器号,等等。 1 2 第一件物品,第1个工序需要在1号机器上进行,第2个工序需要在2号机器上进行 1 2 第二件物品,第1个工序需要在1号机器上进行,第2个工序需要在2号机器上进行 2 1 第三件物品,第1个工序需要在2号机器上进行,第2个工序需要在1号机器上进行 */ for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) cin >> p[i][j]; //每个工件的每个工序的加工时间 //后n行依次表示每个工件的每个工序的加工时间。 for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) cin >> t[i][j]; //找到最长的时间是哪个 int ans = 0; //处理每一个输入顺序 for (int i = 1; i <= n * m; i++) { //利用桶排思路,记录每个工件的加工到第几个工序 cnt[seq[i]]++; int x = seq[i]; //第几个工件 int y = cnt[seq[i]]; //此工件的第几个工序(第几次出现) int mac = p[x][y]; //根据工件+工件的工序--->第几个机器上加工 for (int j = last[x];; j++) { //此工件需要在最后一次加工时间的基础上去尝试,符合规则1,直到找到答案为止 //看看有空的话,能不能放的下去,比如有3个空,但不够长,就不行 if (check(j, t[x][y], mac)) { //标识此位置被占用 for (int k = j; k < j + t[x][y]; k++)res[mac][k] = x; //更新最后的位置值 last[x] = j + t[x][y]; //不断的更新最大值 ans = max(ans, last[x]); break; } } } cout << ans << endl; return 0; }