題目鏈接
題目描述
用2 台處理機A 和B 處理n 個作業。設第i 個作業交給機器A 處理時需要時間i a ,若由機器B 來處理,則需要時間i b 。由於各作業的特點和機器的性能關系,很可能對於某些i,有ai >=bi,而對於某些j,j≠i,有aj < bj 。既不能將一個作業分開由2 台機器處理,也沒有一台機器能同時處理2 個作業。設計一個動態規划算法,使得這2 台機器處理完這n個作業的時間最短(從任何一台機器開工到最后一台機器停工的總時間)。研究一個實例: (a1,a2,a3,a4,a5,a6)=(2,5,7,10,5,2);(b1,b2,b3,b4,b5,b6)=(3,8,4,11,3,4)。 對於給定的2 台處理機A 和B處理n 個作業,找出一個最優調度方案,使2台機器處理完這n 個作業的時間最短。
輸入
的第1行是1個正整數n<=200, 表示要處理n個作業。 接下來的2行中,每行有n 個正整數,分別表示處理機A 和B 處理第i 個作業需要的處理時間。
輸出
最短處理時間
樣例輸入
復制
6 2 5 7 10 5 2 3 8 4 11 3 4
樣例輸出
15
題解:
這道題是說有N個作業可以在兩個機器A,B上操作,同一個作業在A,B上不能同時進行,並且在A,B上的操作時間不同,所以我們要考慮從1~n個作業,哪些在A上,哪些在B上操作,所需要的時間最短。
用動態規划的思想,我們做這樣的思考:當操作第i個作業時,我們選A還是B機器?在題目的要求下,我們就需要根據i-1的操作和i操作之間的關聯來解題了。
先定義變量:a[i]-操作i在機器A上的時間
b[i]-操作i在機器B上的時間
f[i][j]操作到第i個作業時,在A機器已經花費j時間的情況下,找到b機器操作的時間
這道題可以這樣來做:當我們全部選A操作的時候,時間上限為a[i]的和,即suma,所以作業從1~n在A上操作的時間都不會超過suma。
我們就可以在A機器操作時間0<=j<=suma的范圍內,操做到第i個操作時,在B機器上所花的最短時間。
最短時間:1.當a[i] >j時,f[i][j]=f[i-1][j]+b[i];即在操作到i作業時,A機器所花費的時間大於j,所以不能再A機器上操作了,所以這時應該選擇B機器,就要找在操作到i-1作業時,
A機器已經花費j時間的情況下,B機器已經操作的時間f[i-1][j],然后在i操作時選了B,就是f[i-1][j]+b[i]了。
2.當a[i]<=j時,f[i][j]=min(f[i-1][j-a[i]],f[i-1][j]+b[i]);,可能選A機器,可能選B機器,如果選A機器,接要找在操作到i-1作業,A已經花費的時間為j-a[i]時B機器的時間f[i-1][j-a[i]],因為沒選B,所以這時候f[i][j]的時間與f[i-1][j-a[i]]相等。
當操作到第n個操作時,從A機器操作時間0~suma的情況下,各個B機器操作的最短時間就找出來了。我們要在A機器花費時間0~suma的時間段里,逐一比較A,B機器的時間,會按最長的時間選出A,B機器的代表,
再在這suma個時間代表中選出最小的哪一個作為最短花時間。
代碼如下:
#include<bits/stdc++.h> using namespace std; #define MAX 201 int a[MAX];//a[i],A機器 處理i作業花費時間 int b[MAX];//b[i],B機器 處理i作業花費時間 int f[MAX][10000];// f[i][j],在處理i作業時A機器花費j時間的情況下B機器花費的最小時間 int suma=0;//如果所有作業全部由A機器處理,最大時間限制 int min(int x,int y) { return x<y?x:y; } int max(int x,int y) { return x>y?x:y; } int dealWith(int n) { for(int i=1;i<=n;i++) { for(int j=0;j<=suma;j++) { if(a[i]<=j) { f[i][j]=min(f[i-1][j-a[i]],f[i-1][j]+b[i]); } else { f[i][j]=f[i-1][j]+b[i]; } } } int m=99999; for(int j=1;j<=suma;j++) { int t; t=max(j,f[n][j]); m=min(m,t); } return m; } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); suma+=a[i]; } for(int i=1;i<=n;i++) { scanf("%d",&b[i]); } int m=dealWith(n); printf("%d\n",m); return 0; }