zoukankan      html  css  js  c++  java
  • 人参中第一次膜你退货

    洛谷调了调过了……bzoj调了一晚上快把评测卡了还是没过……

    不过还是感觉这个算法肥肠神奇,是一个可以带给人们欢乐的算法。

    算法思想极为简单,先随便得出一个不优解,然后每次在这个不优解的周围随机跳动,随机跳动幅度随时间推移减小,如果到了更优的解则更新;如果解不是更优的则有T的概率更新,T随时间推移减小。

    算法主要难点在于参数的设置,包括初始幅度,幅度减小的速率,还有T。这玩意过于玄学我缺乏人生经验希望有大佬指点一二。

    睿智的模板

    #include<bits/stdc++.h>
    using namespace std;
    struct thing
    {
        double x,y,w;
    }a[1001];
    int n;
    double ansx,ansy,t,ans;
    #define T 0.998
    double calc(double x,double y)
    {
        double res=0;
        for(int i=1;i<=n;i++)
        {
            res+=sqrt((a[i].x-x)*(a[i].x-x)+(a[i].y-y)*(a[i].y-y))*a[i].w;
        }
        return res;
    }
    void fire()
    {
        double xx=ansx,yy=ansy;
        t=1270;
        for(;t>=1e-14;t*=T)
        {
            double x=xx-(rand()*2-RAND_MAX)*t,y=yy-(rand()*2-RAND_MAX)*t;
            double tmp=calc(x,y),d=tmp-ans;
            if(d<0)
            {
                ans=tmp;
                ansx=x,ansy=y,xx=x,yy=y;
            }
            else if( exp(-d/t)*RAND_MAX>rand())
                xx=x,yy=y;
        }
    }
    int main()
    {
        srand(20011115);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a[i].w);
            ansx+=a[i].x,ansy+=a[i].y;
        }
        ansx/=(double)n,ansy/=(double)n;
        ans=calc(ansx,ansy);
        for(int i=1;i<=8;i++)
        fire();
        printf("%.3lf %.3lf",ansx,ansy);
    }
    View Code
  • 相关阅读:
    每天两题02
    每天两题01
    简单看看原码、补码和反码
    简单看看java之枚举
    随意看看AtomicInteger类和CAS
    js原型链
    简单看看jdk7源码之Object和String
    简单学习js
    element的表单校验自动定位到该位置
    for循环使用element的折叠面板遇到的问题-3
  • 原文地址:https://www.cnblogs.com/mordor/p/9776250.html
Copyright © 2011-2022 走看看