zoukankan      html  css  js  c++  java
  • 题解 洛谷 P4044 【[AHOI2014/JSOI2014]保龄球】

    (DP) 来做的话会很麻烦,细节会很多,考虑乱搞一些的做法。(n) 很小,答案和排列顺序有关,所以考虑模拟退火来解决本题。

    产生新状态即为交换当前排列的两个位置。调参时可以采取降低退火次数,升高温度和降温系数来处理,这样正确性会高。

    #include<bits/stdc++.h>
    #define maxn 55
    #define eps 1e-10
    using namespace std;
    template<typename T> inline void read(T &x)
    {
        x=0;char c=getchar();bool flag=false;
        while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        if(flag)x=-x;
    }
    int n,m,ans,cnt=1000;
    struct node
    {
        int a,b;
    }p[maxn];
    int calc()
    {
        int v=0;
        for(int i=1;i<=n+m;++i)
        {
            v+=p[i].a+p[i].b;
            if(p[i-1].a==10) v+=p[i].a+p[i].b;
            else if(p[i-1].a+p[i-1].b==10) v+=p[i].a;
        }
        return v;
    }
    void SA()
    {
        double T=1000000,delta=0.9895;
    	while(T>eps)
    	{
    		int x=rand()%(n+m)+1,y=rand()%(n+m)+1,v;
            while(x==y||(m&&(x==n||y==n))) x=rand()%(n+m)+1,y=rand()%(n+m)+1;
    		swap(p[x],p[y]),v=calc();
    		if(v>ans) ans=v;
    		else if(exp((v-ans)/T)*RAND_MAX<rand()) swap(p[x],p[y]);
    		T*=delta;
    	}
    }
    int main()
    {
        srand((long long)new char),read(n);
        for(int i=1;i<=n;++i) read(p[i].a),read(p[i].b);
        if(p[n].a==10) m=1,read(p[n+1].a),read(p[n+1].b);
        while(cnt--) SA();
        printf("%d",ans);
        return 0;
    }
    
  • 相关阅读:
    多测师讲解htm_L标题标签001_高级讲师 肖sir
    Shell特殊变量介绍与实践 $0
    shell 变量定义技巧总结
    shell 环境变量的知识小结
    前端 chrome查看html样式基本操作
    shell 命令 env
    date 命令
    shell 命令 set命令
    shell export 命令
    前端 html span标签
  • 原文地址:https://www.cnblogs.com/lhm-/p/13520115.html
Copyright © 2011-2022 走看看