zoukankan      html  css  js  c++  java
  • bzoj3877: [Ahoi2014&Jsoi2014]保龄球

    这个题没有思路,然后看起来很可以退火的样子。。。。

    然而强行退火跟sb一样。。。冷静分析了一下好像爬山捉这个更优

    然鹅我不会。。。

    那就瞎搞搞,本机AC贡献了7WA终于过了

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<ctime>
    using namespace std;
    
    int n,bk,ans;
    struct node{int x,y;}a[60],b[60];
    bool cmp(node n1,node n2){return n1.x==n2.x?n1.y<n2.y:n1.x<n2.x;}
    
    int calc()
    {
        int ret=0;
        for(int i=1;i<=bk;i++)
        {
            if(a[i-1].x==10)ret+=(a[i].x+a[i].y)*2;
            else if(a[i-1].x+a[i-1].y==10)ret+=a[i].x*2+a[i].y;
            else ret+=a[i].x+a[i].y;
        }
        ans=max(ans,ret);
        return ret;
    }
    bool check(int i,int j)
    {
        if(a[i].x==a[j].x&&a[i].y==a[j].y)return false;
        if(i==n)swap(i,j);
        if(j==n)
        {
            if(a[j].x==10)return false;
            else if(a[i].x==10)return false;
            return true;
        }
        else return true;
    }
    double myrand(){return double(rand()%10000)/10000.0;}
    void annealing()
    {
        int T=1e6,sum=calc(),ddd;
        while(T>1e-5)
        {
            for(int i=1;i<=10;i++)
            {
                for(int x=1;x<=bk;x++)
                {
                    for(int y=x+1;y<=bk;y++)
                        if(x!=y)
                        {
                            if(check(x,y))
                            {
                                swap(a[x],a[y]);
                                ddd=calc();
                                int delta=ddd-sum;
                                if(delta>0)sum=ddd;
                                else swap(a[x],a[y]);
                 T*=0.97;
                            }
                        }
                }
            }
            for(int i=1;i<=100;i++)
            {
                int x=rand()%bk+1;
                int y=rand()%bk+1; if(y==x){y++;if(y==n+1)y=1;}
                
                if(check(x,y))
                {
                    swap(a[x],a[y]);
                    ddd=calc();
                    int delta=ddd-sum;
                    if(delta>0||exp((double)delta/T)>myrand())sum=ddd;
                    else swap(a[x],a[y]);
                     T*=0.97;
                }
            }
        }
        
        for(int i=1;i<=20;i++)
        {
            int x=rand()%bk+1;
            int y=rand()%bk+1; if(y==x){y++;if(y==n+1)y=1;}
            
            if(check(x,y))
            {
                swap(a[x],a[y]);
                calc();
                swap(a[x],a[y]);
            }
        }
    }
    
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        srand(2003);
        scanf("%d",&n); int x,y,i=1;
        while(scanf("%d%d",&a[i].x,&a[i].y)!=EOF)i++;
        if(i==n+2)bk=n+1;
        else bk=n;
        memcpy(b,a,sizeof(b));
        
        ans=0;
        for(int u=1;u<=50;u++)
        {
            if(bk!=n)swap(a[n],a[n+1]);
            random_shuffle(a+1,a+bk-1+1);
            if(bk!=n)swap(a[n],a[n+1]);
            annealing();
        }
        printf("%d
    ",ans);
        
        return 0;
    }
  • 相关阅读:
    页面上有10个多选框,实现三个按钮(重置、反选、全选)功能
    鼠标点哪 哪出15*15的圆型div
    es写简单的留言板
    面试准备(3)事件循环
    面试准备(2)async+await的使用与原理
    面试准备(1)重排与重绘和验证码
    vue项目修改el-input样式
    echarts画雷达图详解
    决心
    国庆中秋
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/10578195.html
Copyright © 2011-2022 走看看