一、 问题描述
二、算法思想
这是一个经典的作业调度问题,可以使用动态规划来解决。
首先,我们可以将每个任务定义为一个节点,图中的边表示任务的先后顺序。根据题目的要求,每个任务必须先在印刷车间进行印刷,然后再到装订车间进行装订。因此,我们可以将任务之间的先后关系表示为一个有向无环图(DAG)。
接下来,我们定义一个dp数组,dp[i]表示完成前i个任务所需的最少时间。那么,我们可以得到状态转移方程如下: dp[i] = max(dp[j]) + t[i][1] + t[i][2],其中j<i,t[i][1]表示任务i在印刷车间所需的时间,t[i][2]表示任务i在装订车间所需的时间。
最后,我们需要找出dp数组中的最大值,即为完成所有任务所需的最少时间。
三、代码实现
#include <stdio.h>
int wk[10000], work[10000][3];
int mini[3], n;
void Findmi(){int i;for(i = 0; i < n; i++){if(!work[i][2]){if(work[i][0] < mini[0]){mini[0] = work[i][0];mini[1] = 0;mini[2] = i;}if(work[i][1] < mini[0]){mini[0] = work[i][1];mini[1] = 1;mini[2] = i;}}}work[mini[2]][2] = 1;
}
int Time(){int i = 0, j = 0, k = 0, v = 0;for(;j < n; j++){i = k;while(work[wk[j]][0]--)i++;k = i;if(v < k) v = k;i = v;while(work[wk[j]][1]--)i++;v = i;}return i;
}
int main(){int i, k, g;int m;while(scanf("%d", &n) != EOF&&n){m = n; for(i = 0; i < n; i++){scanf("%d%d", work[i]+0, work[i]+1);work[i][2] = 0;}for(k = 0,g = n-1;m > 0; m--){mini[0] = 100000000;Findmi();if(!mini[1]){wk[k] = mini[2];k++;}else{wk[g] = mini[2];g--;}}printf("%d\n", Time());}return 0;
}
执行结果
结语
失败并不可怕
可怕的是你从未尝试过
!!!