Description
有 N 個任務和兩臺機器 A 與 B。每個任務都需要既在機器 A 上執行,又在機器 B 上執行,第 i 個任務需要在機器 A 上執行時間 Ai,且需要在機器 B 上執行時間 Bi。最終的目標是所有任務在 A 和 B 上都執行完,且希望執行完所有任務的總時間儘量少。當然問題沒有這麼簡單,有些任務對於先在機器 A 上執行還是先在機器 B 上執行有一定的限制。據此可將所有任務分爲三類:
1.任務必須先在機器 A 上執行完然後再在機器 B 上執行。
2.任務必須先在機器 B 上執行完然後再在機器 A 上執行。
3.任務沒有限制,既可先在機器 A 上執行,也可先在機器 B 上執行。
現在給定每個任務的類別和需要在機器A和機器B上分別執行的時間,問使所有任務都能按規定完成所需要的最少總時間是多少。
Input
從文件input.txt中讀入數據,輸入文件的第一行只有一個正整數N(1≤N≤20),表示任務的個數。接下來的N行,每行是用空格隔開的三個正整數Ti, Ai, Bi(1≤Ti≤3, 1≤Ai, Bi≤1000),分別表示第i個任務的類別(類別1, 2, 3的定義如上)以及第i個任務需要在機器A和機器B上分別執行的時間。
Output
輸出文件 output.txt 僅包含一個正整數,表示所有任務都執行完所需要的最少總時
Sample Input
3
3 5 7
1 6 1
2 2 6
14
Sample Output
14
Hint
樣例解釋:一種最優任務調度方案爲:機器A上執行的各任務依次安排如下:任務1(0 - 5), 任務2(5 - 11), 任務3(11 - 13);機器B上執行的各任務依次安排如下:任務3(0 - 6), 任務 1(6 - 13), 任務2(13 - 14),這樣,所有任務都執行完所需要的總時間爲14。
題解
乖乖,隨機化。
驚了,還以爲是DP。
枚舉每個3類型到底是1類型還是2類型,然後所有1類型按b時間從大到小排序,所有2類型按a時間從大到小排序,先貪心一下現在的答案。再隨機交換一下做任務的順序,如果更優就更換,如果不優就不換,就這樣。
#include<bits/stdc++.h>
using namespace std;
const int N = 30, inf = 0x3f3f3f3f;
int n, a[N], b[N], t[N];
int stk1[N], top1, stk2[N], top2;
bool wh[N];
int ans = inf;
bool cmp1(int p, int q){
if(b[p] == b[q]) return a[p] < a[q];
return b[p] > b[q];
}
bool cmp2(int p, int q){
if(a[p] == b[q]) return b[p] < b[q];
return a[p] > a[q];
}
void init(){
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d%d%d", &t[i], &a[i], &b[i]);
}
int calc(){
int sa = 0, sb = 0, ret = 0;
for(int i = 1; i <= top2; i++) sb += b[stk2[i]];
for(int i = 1; i <= top1; i++){
sa += a[stk1[i]];
if(sa < sb) sb += b[stk1[i]];
else sb = sa + b[stk1[i]];
}
ret = max(sa, sb);
sa = sb = 0;
for(int i = 1; i <= top1; i++) sa += a[stk1[i]];
for(int i = 1; i <= top2; i++){
sb += b[stk2[i]];
if(sb < sa) sa += a[stk2[i]];
else sa = sb + a[stk2[i]];
}
return max(ret, max(sa, sb));
}
void solve(){
top1 = top2 = 0;
for(int i = 1; i <= n; i++)
if(wh[i]) stk2[++top2] = i; else stk1[++top1] = i;
sort(stk1+1, stk1+top1+1, cmp1);
sort(stk2+1, stk2+top2+1, cmp2);
int ret = calc(), t = 2000, a1, a2, b1, b2, tmp;
while(t--){
if(top1)
swap(stk1[a1 = rand()%top1+1], stk1[a2 = rand()%top1+1]);
if(top2)
swap(stk2[b1 = rand()%top2+1], stk2[b2 = rand()%top2+1]);
tmp = calc();
if(tmp < ret) ret = tmp;
else{
if(top1) swap(stk1[a1], stk1[a2]);
if(top2) swap(stk2[b1], stk2[b2]);
}
}
if(ret < ans) ans = ret;
}
void dfs(int k){
if(k > n) solve();
else
switch(t[k]){
case 1: wh[k] = 0; dfs(k + 1); break;
case 2: wh[k] = 1; dfs(k + 1); break;
case 3: wh[k] = 0; dfs(k + 1); wh[k] = 1; dfs(k + 1); break;
}
}
void work(){
dfs(1);
printf("%d\n", ans);
}
int main(){
srand(10100619);
init();
work();
return 0;
}