达到最高效益的调度
http://blog.csdn.net/wenlei_zhouwl/article/details/5993185
問題:?假設有一臺機器,以及在此機器上處理的n個作業a1,a2,...an的集合。每隔作業aj有一個處理時間tj,效益pj,以及最后期限dj。機器在一個時刻只能處理一個作業,而且作業aj必須在tj連續時間單位內不間斷地運行。如果作業aj在最后期限dj之前完成,則獲得效益pj,但如果在最后期限之后才完成,則沒有效益。請給出一個動態規劃算法,來尋找能獲得最大量效益的調度,假設所有的處理時間都是1到n之間的整數。
分析: ?
其實這個問題類似于01背包問題。
1.??? 將a1,a2,…,an按照dj值排序,從小到大。假設接下來的分析中,已經保證當i<j時,di<dj。添加d0=0。
2.??? 構建數組s[n][d[n]],s[i][j]代表在j時間內,調度i個作業,所得最高效益值。初始時,令s[i][0] = 0(i = 0->n),s[0][j] = 0(j = 0->d[n])。
3.??? 求s[i][j]的值,select[i][j]用于記錄是否選擇i。這里遞歸包含了一種思想:如果第i個作業被調度,那么最好使其在期限時正好結束,這樣能夠保證i之前的作業能夠在更充裕的時間內被調度。
for i = 1->n for j = 1->d[i]//不調度is[i][j] = s[i-1][min(j, d[i-1])]select[i][j] = false//調度iif j>t[i]if s[i][j] < s[i-1][min(j-t[i], d[i-1])]+p[i]s[i][j] = s[i-1][min(j-t[i], d[i-1])]+p[i]select[i][j] = true
我之前任務這就是一個單純的背包問題,不理解上面為什么要排序,為什么要求min
下面的段錯誤的代碼:
int maxV = 0x80000000;int f[N] = {0};for (int i = 0; i < n; ++i ) {for (int v = work[i].deadline; v >= work[i].time; --v) {f[v] = max(f[v],f[v - work[i].time] + work[i].productivity);if (maxV < f[v])maxV = f[v];}}cout<<maxV<<endl;
#define N 10 //每個作業作為一個結點 struct node {int time;//處理時間int productivity;//效益int deadline;//最后期限 }work[N];
這是因為任務有截止期限的,所以必須按照di從小到大排序
下面的代碼比較好理解
sort();int end = deadline[0] - time[0];for (int i = 0; i < end; ++i)f[0][i] = 0;for (int i = end; i<= deadline[0]; ++i)f[0][i] = value[i];for (int i = 1; i < n; ++i) {for (int j = 0; j <= deadline[i]; ++j) {if (j< time[i])//如果結束時間比運行時間還少, 則不能選擇這個作業{f[i][j] = f[i-1][min(j,deadline[i-1])];}else {int end = j - time[i];f[i][j] =max( f[i-1][min(end, deadline[i-1])] + value[i], f[i-1][deadline[i-1]]);//如果和前一個沖突,選與不選的問題}}}
總結
- 上一篇: 一些智力题和算法题
- 下一篇: 1~9组成三个3位的平方数