回溯:最佳調度問題


描述 Description   

        假設有n 個任務由k 個可並行工作的機器完成。完成任務i 需要的時間為ti。試設計一個算法找出完成這n 個任務的最佳調度,使得完成全部任務的時間最早。

一旦任務i由某台機器完成,中途不能更換機器。

編程任務:

對任意給定的整數n 和k,以及完成任務i 需要的時間為ti,i=1~n 。編程計算完成這n個任務的最佳調度

 

 

輸入格式 Input Format

        第一行有2 個正整數n 和k。

第2 行的n 個正整數是完成n 個任務需要的時間。

 

輸出格式 Output Format      

        完成全部任務的最早時間。

 

樣例輸入 Sample Input

7 3

2 14 4 16 6 5 3

 

樣例輸出 Sample Output      

17

 

這道題我最開始寫的時候可以說是zz了,怎么說,最開始連題都沒讀懂,甚至看不出這是道回溯題(我真是太弱啦!!),當時感覺和接水問題差不多(好像確實差不多?不是我的鍋),在lyz大佬的指點下,才算是大概有些頭緒。然后敲了沒幾行又卡了,最后不得已搜了兩篇題解,算是徹底明白這題怎么寫了。

換一個角度思考一下,一個k個可並行的機器,實際就相當於把這k個機器當做容器,將時間填入容器中去,按照時間來搜索,然后一層一層搜索,每次傳的是容器中時間的最大值(在這個時間內我們可以不斷地用其他機器完成別的工作,而當累加時間大於最大時間是,我們就不得已擴充容器了)

//剪枝可以使這個程序快到飛起,否則就等着tle吧….

代碼如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int n,k;
 4 int a[100086],s[100086];
 5 int minn=1000000;
 6 bool ltt(int x,int y){
 7 return x>y;}
 8 inline void dfs(int b,int c){
 9     if(c>=minn) return;//剪枝1號
10     if(b>n){
11         if(c<minn)
12             minn=c;
13         return;
14     }
15     for(int i=1;i<=k;i++){
16         if(s[i]+a[b]<=minn){//剪枝2號
17             s[i]+=a[b];
18             dfs(b+1,max(c,s[i]));
19             s[i]-=a[b];
20         }
21     }
22     return;
23 }
24 int main() {
25     cin>>n>>k;
26     memset(s,0,sizeof(s));
27     for(int i=1;i<=n;i++)
28         cin>>a[i];
29     sort(a+1,a+n+1,ltt);//從大到小排序可以更快接近最優解
30     dfs(1,0);
31     cout<<minn<<endl;
32     return 0;
33 }
View Code

 


免責聲明!

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



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