zoukankan      html  css  js  c++  java
  • 某题 模拟退火

    为了防止某天忘了默默的屯下来...

    参考的skyh的代码而写的(虽然大部分都一样吧....)

    网上褪的话:增加十倍的初温与末温比值只会增加约25%的迭代次数,而往0.9…99的后面加个9会增加十倍的运行时间。(t==1000不是跑了1000遍的)

    #include<ctime>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    const double cg=0.973;
    const int maxn=100005;
    int n,h[maxn];
    int turn[maxn],x;
    ll ans;
    inline int abs(int x){return (x^(x>>31))-(x>>31);}
    ll check(int pos)//模拟位置通过位置知高度再去算代价
    {
        for(register int i=1;i<=pos;++i)  turn[i]=h[i]+pos-i;
        for(register int i=pos+1;i<=n;++i)  turn[i]=h[i]+i-pos;
        int mid=(1+n)>>1;//奇数个显然,偶数个的话左右两个数选谁代价同因为列式子左右两边的两个数和抵消了该数的贡献
        nth_element(turn+1,turn+mid,turn+n+1);
        x=turn[mid];
        if(x<pos)  x=pos;
        if(n-pos+1>x)  x=n-pos+1;    //这两个if是把不合法的情况(0)排除正确性是因为当x,它们时我把x换过去不就是换了个离中位数最近的吗。所以是对的
        ll cost=0;
        for(register int i=1;i<=n;++i)  cost+=abs(x-turn[i]);
        return cost;
    }
    inline int read()
    {
        int t=0;  char ch=getchar();
        while(ch<'0'||ch>'9')  ch=getchar();
        while(ch>='0'&&ch<='9')  t=(t<<3)+(t<<1)+(ch^48),ch=getchar();
        return t;
    }
    int main()
    {
        srand(time(0));
        n=read();
        for(register int i=1;i<=n;++i)  h[i]=read();
        double T=985,dt=1e-5;
        int tmp,now=(1+n)>>1;
        ll turnans,nowans,dta;
        nowans=check(now);  ans=nowans;
        while(T>dt)
        {
            tmp=now+(2ll*rand()-0x7fffffff)*T*0.000001;//保证rand数的随机摆动性左右摆动,rand出来的可能很大*0.000001
            if(T<1.00)  tmp=max(tmp,1),tmp=min(tmp,n);//别rand出去
            else tmp=(tmp%n+n-1)%n+1;//在确保正数情况下rand一个1-n的数
            turnans=check(tmp),dta=turnans-nowans;
            if(turnans<nowans||exp(-dta/T)*0x7fffffff>rand())  nowans=turnans,now=tmp;//nowans只是我们用来找最优解的一个东西
            if(turnans<ans)  ans=turnans;//维护最终结果。
            T*=cg;//退火降温
        }
        printf("%lld",ans);
        return 0;
    }

  • 相关阅读:
    Python的命名空间及作用域
    STM32 RTC时钟的配置
    STM32 输入捕获配置
    stm32 看门狗配置
    led灯的驱动电流和电阻
    STM32中TIMx的映射及其通道
    STM32中断定时,控制LED灯
    STM32 用c语言控制4个LED灯从左向右无限流动
    SYSTEMsyssys.c:33:7: error: expected '(' before 'void' __ASM void MSR_MSP(u32 addr)
    STM32 PWM输出(映射)
  • 原文地址:https://www.cnblogs.com/three-D/p/11321107.html
Copyright © 2011-2022 走看看