愿各位程序员都能记住,输出第一条hello world时候的心情。坚持下去,你的每一条代码都在默默的改变世界,加油!加油!加油! “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。 什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。 人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。

模拟退火 [JSOI2004]平衡点 / 吊打XXX

 

本人水平有限,题解不到为处,请多多谅解

 

本蒟蒻谢谢大家观看

 

 

题目传送门

 

大致的模拟退火讲解我这里不再赘述,如有疑问请看这里

传送门连接

 

code:

#include <bits/stdc++.h>
#define down 0.996//徐徐降温 
using namespace std;
int n;
struct node{
int x;
int y;
int w;
}object[2005];//存下物体的坐标 
double ansx,ansy,answ;//最终答案 
double energy(double x,double y)//根据物理学知识,能量总和越小越稳定 
{
   double r=0,dx,dy;
   for (int a=1;a<=n;a++)
   {
      dx=x-object[a].x;
      dy=y-object[a].y;
      r+=sqrt(dx*dx+dy*dy)*object[a].w;
   }
      return r;
}
void sa()//模拟退火 
{
   double t=3000;//温度要足够高 
   while (t>1e-15)//略大于0 
   {
       //生成[-T*RAND_MAX,T*RAND_MAX)的随机变动范围(rand():[0,RAND_MAX))
       //rand()一个随机数,RAND_MAX随机范围内最大值
      double ex=ansx+(rand()*2-RAND_MAX)*t;//随机产生新的答案 
      double ey=ansy+(rand()*2-RAND_MAX)*t;
      double ew=energy(ex,ey);
      double de=ew-answ;
      if (de<0)//如果此答案更优,就接受 
      {
         ansx=ex;
         ansy=ey;
         answ=ew;
      }
      else if(exp(-de/t)*RAND_MAX>rand())
      //以概率exp(-Δt′/T)接受S′作为新的当前解S。
      //否则根据多项式概率接受 
      {
         ansx=ex;
         ansy=ey;
      }
      t*=down;
   }
}
void solve()//多跑几遍退火,增加得到最优解的概率 
{
   sa();
   sa();
   sa();
   sa();
}
int main() 
{
    cin>>n;
    for (int a=1;a<=n;a++)
    {
           scanf("%d%d%d",&object[a].x,&object[a].y,&object[a].w);
           ansx+=object[a].x;
           ansy+=object[a].y;
    }
        ansx/=n;//以平均数作为初始答案 
        ansy/=n;
        answ=energy(ansx,ansy);
        solve();
        printf("%.3lf %.3lf\n",ansx,ansy);//华丽的输出 
            return 0;
}

 

posted @ 2019-09-22 19:44  max_lemon  阅读(185)  评论(0编辑  收藏  举报
Live2D
别人恋爱不成功,你连暗恋都不成功! 你写不出代码的原因只有一个,那就是你没有彻底理解这个算法的思想!!-----沃茨·基硕德