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 }

 

posted @ 2017-11-29 13:32  wfj_2048  阅读(347)  评论(0编辑  收藏  举报