• BZOJ2336: [HNOI2011]任务调度


    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
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    002变量
    001Java输入、eclipse快捷键
    040同步条件event
    kali配置ip,更新源,更新签名
    039条件变量同步(Condition)
    038信号量
    037多线程同步
    配置java环境变量(详细)
    提高你的Python能力:理解单元测试
    电影里的代码之《机械姬》:筛法求质数
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/9488226.html
Copyright © 2020-2023  润新知