zoukankan      html  css  js  c++  java
  • P2210 Haywire 模拟退火 状压DP

    P2210 Haywire 模拟退火 状压DP

    在一条轴上给定(N)个点,每个点有三个朋友,要求一种排列使得每个点到朋友距离之和之和最小。

    [Nleq 12 ,N \% 2 == 0 ]

    分析

    状压DP本人学艺不精,没有想到(但好像数据量很像?)

    此题可以作为模拟退火的模板题

    模拟退火最重要的三个参数:起始温度,终止温度,温度变化速率

    模拟退火的关键还在于几率接受

    设当前温度为(T),当前解为(k) ,最优解为(K_{max}) ,我们有一定几率接受差解

    [exp((k-max)/T) < (double)rand()/RAND\_MAX ]

    此题可以通过交换两个点的位置来得到新的解

    代码

    int f[15][3];
    int pos[15];
    int best = INF;
    int n;
    
    int get_cost() {
        int tmp = 0;
        for (int i = 1; i <= n; i++)
            for (int j = 0; j < 3; j++)
                tmp += abs(pos[i] - pos[f[i][j]]);
        return tmp;
    }
    
    const double beginT = 10000, endT = 1e-12, delT = 0.99;
    
    void SA(int times) {
        int x, y, tmp;
        while (times--) {   //模拟退火次数
            for (double T = beginT; T > endT; T *= delT) {
                do {
                    x = rand() % n + 1;
                    y = rand() % n + 1;
                } while (x == y);
                swap(pos[x], pos[y]);
                tmp = get_cost();  //求出当前解
                if (tmp <= best)
                    best = tmp;
                else if (exp(best - tmp) / T > (double)rand() / RAND_MAX)
                    swap(pos[x], pos[y]); //一定几率不接受
            }
        }
    }
    
    int main() {
        srand(time(0)); //随机种子
        n = readint();
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < 3; j++)
                f[i][j] = readint();
            pos[i] = i;
        }
        SA(275);
        Put(best / 2);
    }
    
  • 相关阅读:
    WCF的一些基本知识点
    WCF服务编程基础
    Spring IoC 原理猜想(转载)
    利用httponly提升应用程序安全性(转载)
    Ajax:CustomValidator对输入的文本框进行验证
    WCF学习系列
    WCF 契约
    JavaScript:search() 方法
    HDU 1596 find the safest road
    HDU 2063 过山车
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13623747.html
Copyright © 2011-2022 走看看