SWUST OJ 698(dp)
阿新 • • 發佈:2018-12-24
1000(ms) 65535(kb) 1006 / 2689
用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
思路:之前做過類似題目,這裡主要是dp將每個任務進行分配,然後再找總的最小時間。現在用dp[i][j]表示A機器花費時間大於等於j的前提下,任務i給B機器完成的最小時間。
顯然狀態轉移有當 j<a[i-1]時候應該分配給B機器完成,這時候dp[i][j]=dp[i-1][j]+b[i-1];列舉i的時候向後增大一位,因為後面一個的狀態只與前面一個有關。
而當j>=a[i-1]時候,考慮分配給A機器還是B機器,顯然dp[i][j]=min(dp[i-1][j-a[i-1]],dp[i-1][j]+b[i-1]);
#include<bits/stdc++.h> using namespace std; const int INF=0x3f3f3f; const int maxn=300; const int maxm=3000; int dp[maxn][maxm]; //dp[i][j]表示第i個作業由A完成的時間不超過j的前提下B完成的最少時間。 int a[maxn],b[maxn]; int main() { int n; while(~scanf("%d",&n)) { int sum=0; for(int i=0; i<n; i++) { scanf("%d",&a[i]); sum+=a[i]; } for(int i=0; i<n; i++) scanf("%d",&b[i]); memset(dp,0,sizeof(dp)); for(int i=1; i<=n; i++) { for(int j=0; j<=sum; j++)//列舉需要的時間 { if(j<a[i-1]) dp[i][j]=dp[i-1][j]+b[i-1]; //j<a[i-1]時候交給B完成 else dp[i][j]=min(dp[i-1][j-a[i-1]],dp[i-1][j]+b[i-1]); //j>=a[i-1]時候考慮給A完成還是B完成,給A完成時,B花費時間為dp[i-1][j-a[i-1]] //B完成時,B花費時間為dp[i-1][j]+b[i-1] } } //上面將所有工作分配完成,現在統計最少時間dp[n][i]為B完成時間,i為A完成時間 int temp,ans=INF; for(int i=0; i<=sum; i++) { temp=max(dp[n][i],i); if(temp<ans) ans=temp; } printf("%d\n",ans); } return 0; }