bzoj2336 [HNOI2011]任务调度
Description
正解:搜索+随机化。
先写个搜索,枚举所有没有要求的任务属于哪一种任务,然后再用爬山来更新最优解。
具体来说就是先把所有先做任务$A$的按照$a$时间从大到小排序,先做任务$B$的同。然后每次随机交换两个任务的位置,看这样会不会更优。
计算最优解写一个贪心就行了。
1 #include <bits/stdc++.h> 2 #define il inline 3 #define RG register 4 #define ll long long 5 6 using namespace std; 7 8 struct data{ int t,a,b; }q[30]; 9 10 int st1[30],st2[30],vis[30],n,ans,top1,top2; 11 12 il int gi(){ 13 RG int x=0,q=1; RG char ch=getchar(); 14 while ((ch<'0' || ch>'9') && ch!='-') ch=getchar(); 15 if (ch=='-') q=-1,ch=getchar(); 16 while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); 17 return q*x; 18 } 19 20 il int cmp1(const int &x,const int &y){ 21 if (q[x].b==q[y].b) return q[x].a<q[y].a; 22 return q[x].b>q[y].b; 23 } 24 25 il int cmp2(const int &x,const int &y){ 26 if (q[x].a==q[y].a) return q[x].b<q[y].b; 27 return q[x].a>q[y].a; 28 } 29 30 il int calc(){ 31 RG int ta=0,tb=0,res=0; 32 for (RG int i=1;i<=top2;++i) tb+=q[st2[i]].b; 33 for (RG int i=1;i<=top1;++i){ 34 ta+=q[st1[i]].a; 35 if (ta<tb) tb+=q[st1[i]].b; 36 else tb=ta+q[st1[i]].b; 37 } 38 res=tb,ta=tb=0; 39 for (RG int i=1;i<=top1;++i) ta+=q[st1[i]].a; 40 for (RG int i=1;i<=top2;++i){ 41 tb+=q[st2[i]].b; 42 if (tb<ta) ta+=q[st2[i]].a; 43 else ta=tb+q[st2[i]].a; 44 } 45 return max(res,ta); 46 } 47 48 il void check(){ 49 top1=top2=0; 50 for (RG int i=1;i<=n;++i) 51 if (vis[i]==1) st1[++top1]=i; else st2[++top2]=i; 52 sort(st1+1,st1+top1+1,cmp1),sort(st2+1,st2+top2+1,cmp2); 53 RG int T=2000,a1,a2,b1,b2,tmp,res=calc(); 54 while (T--){ 55 if (top1) swap(st1[a1=rand()%top1+1],st1[a2=rand()%top1+1]); 56 if (top2) swap(st2[b1=rand()%top2+1],st2[b2=rand()%top2+1]); 57 tmp=calc(); if (res>=tmp){ res=tmp; continue; } 58 if (top1) swap(st1[a1],st1[a2]); 59 if (top2) swap(st2[b1],st2[b2]); 60 } 61 ans=min(ans,res); return; 62 } 63 64 il void dfs(RG int x){ 65 if (x>n){ check(); return; } 66 if (q[x].t!=3) vis[x]=q[x].t,dfs(x+1); 67 else vis[x]=1,dfs(x+1),vis[x]=2,dfs(x+1); 68 return; 69 } 70 71 int main(){ 72 #ifndef ONLINE_JUDGE 73 freopen("task.in","r",stdin); 74 freopen("task.out","w",stdout); 75 #endif 76 srand(19260817); 77 n=gi(),ans=1<<30; 78 for (RG int i=1;i<=n;++i) q[i].t=gi(),q[i].a=gi(),q[i].b=gi(); 79 dfs(1),cout<<ans; return 0; 80 }