ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

模拟赛-12 connect

2020-06-26 11:02:41  阅读:215  来源: 互联网

标签:sz 12 机器 连线 累加 选中 connect 集合 模拟


题意

工厂里有 \(N\) 个机器,每个机器与其他若干个机器之间需要连线,现在要将这 \(N\) 个机器安放在 \(1\)~\(N\) 这 \(N\) 个位置上,两个处在 \(D_i\) 和 \(D_j\) 位置的机器连线费用为 \(|D_i-D_j|\),求最小的连线费用。
\(1\le N\le 20\)

输入

第一行两个整数 \(N,M\) 表示机器的数量和需要连线的关系数
接下来 \(M\) 行,每行 \(2\) 个数字 \(x,y\) 表示机器 \(x\) 和机器 \(y\) 之间需要连线

输出

一行一个整数表示最小花费

Solution

解法1:玄学

没想出来怎么状压只好退了个火
没想到竟然碾标算/jk

最开始就初始化一个位置数组 \(p\),\(p[i]\) 表示第 \(i\) 台机器的位置
然后每次随机交换两个位置, \(N^2\) 统计新的花费,以 \(exp(-diff/T)\) 的概率接受坏解(以后可能变优)

然后大概 \(30\) 次退火就A了/fad
用时500+ms,std用时1600+ms

解法2:正解状压

首先对于状压的一个状态 \(i\) 要理解到底是啥意思

设二进制表示下的 \(i\) 有 \(x\) 个 \(1\),那么这个状态表示这 \(x\) 个 \(1\) 的位置的机器安放在了 \(1\)~\(x\) 位置
所以我们枚举一台未安放的机器把他放在第 \(x+1\) 位

假设当前状态为 \(i\) 我们枚举机器 \(j\) 放在第 \(x+1\) 位(\((i\&(1<<j))==0\))
但是这个代价就不能 \(O(N)\) 再去算一次了,不然就成了 \(O(N^2 2^N)\) 当场写假掉

我们可以计算对于每一个状态 \(i\) 有多少对冲突的关系(边的端点分别在已选中集合和未选中集合的边数),在安排机器的时候累加即可

正确性:假如第 \(i\) 次加入选中集合的机器需要和第 \(j\) 次加入选中集合的机器连边,为了方便描述我们设 \(i<j\)
那么在 \(i\) 加入选中集合之前边 \((i,j)\) 是不会累加的(因为这条边两端都在未选中集合),在 \(i\) 加入集合之后开始累加,累加到 \(j\) 加入集合为止,\(j\) 加入集合之后这条边的两端又在同一个集合中,不再累加,总共累加 \(j-i\) 次,刚好就是这个关系的花费

这个关系怎么求嘛....
首先我们先计算一个东西,状态 \(i\) 的二进制表示下 \(1\) 的个数,设为 \(sz[i]\) 递推即可: \(sz[i]=sz[i>>1]+(i\&1)\)

然后对于每一台机器 \(u\),在输入的时候就处理出一个数组 \(a[u]\) 表示需要和点 \(u\) 连接的若干台机器的二进制表示

设状态 \(i\) 的冲突关系数为 \(s[i]\) 那么有 \(sum[i]=\sum\limits_{j=0}^{N}sz[i\&a[j]]\) \(((1<<j)\& i==0)\)
(找出一个没选的数字,然后把既和他要连边也已经选取的数字累加进去)

状态转移方程: \(F[i|(1<<j)]=F[i]+s[i]\)
鸽完了/cy

标签:sz,12,机器,连线,累加,选中,connect,集合,模拟
来源: https://www.cnblogs.com/ShadderLeave/p/13194089.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有