题目链接
有 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.txt中读入数据,输入文件的第一行只有一个正整数N(1≤N≤20),表示任务的个数。接下来的N行,每行是用空格隔开的三个正整数Ti, Ai, Bi(1≤Ti≤3, 1≤Ai, Bi≤1000),分别表示第i个任务的类别(类别1, 2, 3的定义如上)以及第i个任务需要在机器A和机器B上分别执行的时间。
输出文件 output.txt 仅包含一个正整数,表示所有任务都执行完所需要的最少总时
3
3 5 7
1 6 1
2 2 6
14
14
样例解释:一种最优任务调度方案为:机器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
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;
}