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\n",ans);
    
    return 0;
}

 

posted @ 2019-03-22 14:48  AKCqhzdy  阅读(105)  评论(0编辑  收藏  举报