動態規划——獨立任務最優調度(Independent Task Scheduling)


題目鏈接

題目描述

用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;
 } 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM