BZOJ2336: [HNOI2011]任务调度
Description

题解Here!
这个题一眼看去贪心对吧。。。
我们枚举第3种任务先跑$A$还是$B$。
这样是$2^{20}$的。
但是有时候贪心可能并不是对的。。。
所以我们可以在贪心基础上加上随机化。
大力随机交换$A,B$机器任务执行的先后顺序,贪心计算时间。
如果更优就保存,大概每次随机$2000$次够了。
模拟退火好像被卡常了,不清楚。。。
附代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#define MAXN 25
using namespace std;
int n,ans=2147483646;
int top_A,top_B,que_A[MAXN],que_B[MAXN];
bool flag[MAXN];
struct Task{
int t,a,b;
}a[MAXN];
inline int read(){
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
inline bool cmp1(const int &p,const int &q){
if(a[p].b==a[q].b)return a[p].a<a[q].a;
return a[p].b>a[q].b;
}
inline bool cmp2(const int &p,const int &q){
if(a[p].a==a[q].a)return a[p].b<a[q].b;
return a[p].a>a[q].a;
}
int calculate(){
int sum_A=0,sum_B=0,s=0;
for(int i=1;i<=top_A;i++)sum_A+=a[que_A[i]].a;
for(int i=1;i<=top_B;i++){
sum_B+=a[que_B[i]].b;
if(sum_A>sum_B)sum_A+=a[que_B[i]].a;
else sum_A=sum_B+a[que_B[i]].a;
}
s=max(sum_A,sum_B);
sum_A=sum_B=0;
for(int i=1;i<=top_B;i++)sum_B+=a[que_B[i]].b;
for(int i=1;i<=top_A;i++){
sum_A+=a[que_A[i]].a;
if(sum_B>sum_A)sum_B+=a[que_A[i]].b;
else sum_B=sum_A+a[que_A[i]].b;
}
s=max(s,max(sum_A,sum_B));
return s;
}
void solve(){
top_A=top_B=0;
for(int i=1;i<=n;i++){
if(flag[i])que_B[++top_B]=i;
else que_A[++top_A]=i;
}
sort(que_A+1,que_A+top_A+1,cmp1);
sort(que_B+1,que_B+top_B+1,cmp2);
int s=calculate();
for(int cases=1;cases<=2000;cases++){
int a1,a2,b1,b2;
if(top_A){
a1=rand()%top_A+1;a2=rand()%top_A+1;
swap(que_A[a1],que_A[a2]);
}
if(top_B){
b1=rand()%top_B+1;b2=rand()%top_B+1;
swap(que_B[b1],que_B[b2]);
}
int now=calculate();
if(now<s)s=now;
else{
if(top_A)swap(que_A[a1],que_A[a2]);
if(top_B)swap(que_B[b1],que_B[b2]);
}
}
ans=min(ans,s);
}
void dfs(int x){
if(x>n){
solve();
return;
}
if(a[x].t==1){flag[x]=false;dfs(x+1);}
else if(a[x].t==2){flag[x]=true;dfs(x+1);}
else{
flag[x]=false;dfs(x+1);
flag[x]=true;dfs(x+1);
}
}
int main(){
srand(2002);
n=read();
for(int i=1;i<=n;i++){a[i].t=read();a[i].a=read();a[i].b=read();}
dfs(1);
printf("%d\n",ans);
return 0;
}

浙公网安备 33010602011771号