• CodeVS1344 线型网络


    题目描述 Description

    有 N ( <=20 ) 台 PC 放在机房内,现在要求由你选定一台 PC,用共 N-1 条网线从这台机器开始一台接一台地依次连接他们,最后接到哪个以及连接的顺序也是由你选定的,为了节省材料,网线都拉直。求最少需要一次性购买多长的网 线。(说白了,就是找出 N 的一个排列 P1 P2 P3 ..PN 然后 P1 -> P2 -> P3 -> ... -> PN 找出 |P1P2|+|P2P3|+...+|PN-1PN| 长度的最小值)

    输入描述 Input Description

    第一行 N ,下面 N 行,每行分别为机器的坐标(x,y) ( 实数 -100<=x,y<=100 )

    输出描述 Output Description

    最小的长度,保留两位小数。

    样例输入 Sample Input

    3
    0 0
    1 1
    1 -1

    样例输出 Sample Output

    2.83

    正解:爬山算法。

    首先这题很容易可以得到一个$O(2^{n}n^{2})$的状压$DP$的算法。然后就不会做了。。

    然后这题可以写爬山算法。。我们打乱$[1,n]$的序列,然后$O(n^{2})$枚举每个$i$和$j$。

    如果$dis(i-1,i)+dis(j,j+1)>dis(i-1,j)+dis(i,j+1)$,那么将$[i,j]$直接翻转一下,可以发现,这样做肯定会得到更优解。然后$rand$3000次,每次$O(n^{2})$算出最优解后取个$min$就行了。

     1 //It is made by wfj_2048~
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <complex>
     5 #include <cstring>
     6 #include <cstdlib>
     7 #include <cstdio>
     8 #include <vector>
     9 #include <cmath>
    10 #include <queue>
    11 #include <stack>
    12 #include <map>
    13 #include <set>
    14 #include <ctime>
    15 #define inf (1e18)
    16 #define eps (1e-9)
    17 #define all (1<<n)
    18 #define N (1<<20)
    19 #define il inline
    20 #define RG register
    21 #define ll long long
    22 #define lb(x) (x & -x)
    23 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
    24 
    25 using namespace std;
    26 
    27 double f[21][N],dd[23][23],x[21],y[21],ans=inf;
    28 int dex[23],n;
    29 
    30 il int gi(){
    31     RG int x=0,q=1; RG char ch=getchar(); while ((ch<'0' || ch>'9') && ch!='-') ch=getchar();
    32     if (ch=='-') q=-1,ch=getchar(); while (ch>='0' && ch<='9') x=x*10+ch-48,ch=getchar(); return q*x;
    33 }
    34 
    35 il double dis(RG int i,RG int j){ return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j])); }
    36 
    37 /*
    38 il void work(){
    39     cin>>n; for (RG int i=1;i<=n;++i) scanf("%lf%lf",&x[i],&y[i]);
    40     for (RG int s=1;s<all;++s){
    41     for (RG int i=1;i<=n;++i){
    42         if (!(s&(1<<(i-1)))) continue;
    43         for (RG int j=1;j<=n;++j){
    44         if (s&(1<<(j-1))) continue;
    45         RG int k=s|(1<<(j-1));
    46         if (f[j][k]<eps) f[j][k]=inf;
    47         f[j][k]=min(f[j][k],f[i][s]+dis(i,j));
    48         }
    49     }
    50     }
    51     for (RG int i=1;i<=n;++i) if (f[i][all-1]>eps) ans=min(ans,f[i][all-1]);
    52     printf("%0.2lf",ans); return;
    53 }
    54 */
    55 
    56 il void sv(RG int a,RG int b){
    57     for (RG int i=a,j=b;i<=j;++i,--j) swap(dex[i],dex[j]);
    58     return;
    59 }
    60 
    61 il double solve(){
    62     for (RG int i=1;i<=100;++i){
    63     RG int a=rand()%n+1;
    64     RG int b=rand()%n+1;
    65     swap(dex[a],dex[b]);
    66     }
    67     for (RG int i=1;i<n;++i)
    68     for (RG int j=i+1;j<=n;++j)
    69         if (dd[dex[i-1]][dex[i]]+dd[dex[j]][dex[j+1]]>dd[dex[i-1]][dex[j]]+dd[dex[i]][dex[j+1]]) sv(i,j);
    70     RG double res=0; for (RG int i=1;i<n;++i) res+=dd[dex[i]][dex[i+1]]; return res;
    71 }
    72 
    73 il void work(){
    74     cin>>n; for (RG int i=1;i<=n;++i) scanf("%lf%lf",&x[i],&y[i]),dex[i]=i;
    75     for (RG int i=1;i<=n;++i)
    76     for (RG int j=1;j<=n;++j)
    77         if (i!=j) dd[i][j]=dis(i,j);
    78     for (RG int i=1;i<=3000;++i){
    79     RG double res=solve();
    80     if (ans>res) ans=res;
    81     }
    82     printf("%0.2lf",ans); return;
    83 }
    84 
    85 int main(){
    86     File("linec");
    87     srand(time(NULL));
    88     work();
    89     return 0;
    90 }
  • 相关阅读:
    djangoadmin实现文件上传下载
    Apscheduler详解(转)
    django集成Apscheduler3
    springboot实现token鉴权
    xss攻击入门
    回顾2012——运维工作周年祭
    9个常用iptables配置实例
    ardunio 实验:超声波测距、声光报警模拟倒车雷达
    一款我用了好多年的多线程FTP软件
    线程Thread基础学习(2)
  • 原文地址:https://www.cnblogs.com/wfj2048/p/6629090.html
Copyright © 2020-2023  润新知