• 【洛谷1337】[JSOI2004] 吊打XXX(模拟退火经典题)


    点此看题面

    大致题意: 一个平面上有(n)个点,每个点有1个权值,现在要选择平面上的一个点,使这(n)个点的权值乘上到达选定点的距离之和最小。

    模拟退火

    我们可以用模拟退火来做这道题。

    先将((0,0))设定为答案,随后不断选取一个新的坐标,比较选择该点时的代价与当前答案的代价。若小于当前答案的代价,则更新答案,否则,将有一定概率更新答案(更新坐标的幅度时间的增大减小更新答案的概率时间的增大以及两个代价之差的增大减小)。

    只要多模拟退火几遍,或者保持一颗虔诚的心,就能过了。

    代码

    #include<bits/stdc++.h>
    #define max(x,y) ((x)>(y)?(x):(y))
    #define min(x,y) ((x)<(y)?(x):(y))
    #define LL long long
    #define swap(x,y) (x^=y,y^=x,x^=y)
    #define delta 0.99
    #define N 1000
    using namespace std;
    int n,x[N+5],y[N+5],w[N+5];
    inline char tc()
    {
        static char ff[100000],*A=ff,*B=ff;
        return A==B&&(B=(A=ff)+fread(ff,1,100000,stdin),A==B)?EOF:*A++;
    }
    inline void read(int &x)
    {
        x=0;int f=1;char ch;
        while(!isdigit(ch=tc())) f=ch^'-'?1:-1;
        while(x=(x<<3)+(x<<1)+ch-'0',isdigit(ch=tc()));
        x*=f;
    }
    inline void write(int x)
    {
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);
        putchar(x%10+'0');
    }
    inline double dis(double nx,double ny)//计算出n个点的权值乘上到选定点的距离之和
    {
        register int i;double res=0.0;
        for(i=1;i<=n;++i) res+=(double)sqrt((x[i]-nx)*(x[i]-nx)+(y[i]-ny)*(y[i]-ny))*w[i];
        return res;
    }
    inline void SA(double &X,double &Y)//Simulated Annealing,模拟退火
    {
        double tt=3000,res=dis(X,Y);//tt表示变化量,res表示当前代价
        while(tt>0.000000000000001)
        {
            double nx=X+(rand()*2-RAND_MAX)*tt,ny=Y+(rand()*2-RAND_MAX)*tt,new_res=dis(nx,ny);//计算出新的坐标以及新的代价
            if(new_res<res||exp((res-new_res)/tt)*RAND_MAX>rand()) res=new_res,X=nx,Y=ny;//如果新的代价小于当前代价,或在一定的几率下,更新当前状态
            tt*=delta;//将变化量减小,是一个模拟物理学上的退火操作的过程
        }
    }
    int main()
    {
        srand(time(NULL)),srand(rand()),srand(rand());
        register int i;
        for(read(n),i=1;i<=n;++i) read(x[i]),read(y[i]),read(w[i]);
        double ans_x=0.0,ans_y=0.0;
        for(i=1;i<=10;++i) SA(ans_x,ans_y);//模拟退火10次
        return printf("%.3lf %.3lf",ans_x,ans_y),0;
    }
    
    
  • 相关阅读:
    [转]中英文停止词表(stopword)
    [转]Memcached常用命令及使用说明
    Java导出excel并下载功能
    Java List 汉字进行排序
    Tengine笔记3:Nginx的反向代理和健康状态检查
    Tengine笔记2:通过IP、域名、端口实现虚拟主机
    Tengine笔记1:安装Tengine和Tengine说明
    Linux学习笔记6-Linux根目录下各个目录的作用
    Linux学习笔记5-搭建内网Yum源
    Python学习笔记10-Python MysqlHelper ,MySql 辅助类
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu1337.html
Copyright © 2020-2023  润新知