从旅行商问题谈状态压缩DP孤独·粲泽

一个商品推销员要去若干个城市推销商品,该推销员从一个城市出发,需要经过所有城市后,回到出发地。应如何选择行进路线,以使总的行程最短?请输出最短行程。节点个数\(N\)满足\(2\leqN\leq20\),路的长度小于\(1000\)。

我们知道,动态规划是根据之前已经计算好的状态推出后面一种状态,这道题亦是如此。也许有人会说,跑一遍最短路不就好了吗?但是最短路不保证走遍每一个点,而即使我们加上了点的计数,那也不能保证从\(A\)上不存在一个环(往回走的环),其节点个数恰好弥补了那些没扫过的节点。而且计数的时候还没到终点的点该如何更新呢?说不定一不小心就更没了,而且如果把每种情况都记录下来,是不亚于枚举的。但是仍有一些弱数据可以被水过去(NOIP),而且这种求最小值的状态压缩题甚至可以被一些优秀的随机化算法(模拟退火)等水过去。不过这些算法最怕的就是求所有状态的题目了,而状态压缩DP就做到了求出所有状态这一点。

由于博主水平有限,无法带领大家一步一步推理,因此我们就针对递推式进行讲解吧。其递推式为:

其中\(f[S][v]\)表示的是从\(v\)出发访问所有不属于集合\(S\)的顶点,最终回到\(0\)的路径的权重总和的最小值。而集合\(V\)表示为所有城市的集合,不难理解从\(0\)到\(0\)就是路程为\(0\)对吧,并且再将其它所有情况均赋值为无穷大(当然不可能是无穷大啊,找一个达不到的值即可),以防计算不存在的情况。其他的话,递推式已经表达得很明白了,大家也可以举几个例子帮助自己理解(注意,里面有些状态是对答案没用的,大家可以找一找,后面我会提到)。

注意这里出现了集合表示法,但是似乎不好怎么表示这个集合,难道用\(set\)表示吗?那就慢了!别忘了二进制这个好东西。

注意到我们的\(int\)可以表示到\(2^{31}-1\),然而这里的\(N\)才这么大一点,那么我们就可以在二进制位中逐位保存某个点“存在”和“不存在”的情况。再者,这只需涉及到二进制的位运算,所以整体来说还是很快的。

那么我们现在来为一些稍缺知识的同学补充一些二进制表达集合的方法吧!

二进制表达想必学过一些二进制的人都知道吧,我们需要做的仅仅是摒弃它的十进制的模样(别影响了自己的理性思维)。假设现在有一个集合\(S=\emptyset\),表示为二进制就是\(00000000\)(假装只有\(8\)位),然后我们往里面加入\(0\),那么在二进制位的第\(0\)位就要改为\(1\),也就是\(S=S\cup\{0\}=S\vee2^0=S|1<<0\)。同理,如果往里面加入\(6\),就是\(S|=1<<6\)(此处计算机表示法均用C++表达)。

如果是判断\(u\)是否存在于集合\(S\)中的话,那么只需要判断\(S\vee2^u\)(即C++中的\(S\And(1<

注意,这道题十分卡常!仍然需要优化!但请一步一步看下来,不要急于求成!

下面这段代码仅能得到\(80\)分,但是开\(O2\)可以险过。

#include#include#defineINF20000usingnamespacestd;intf[(1<<20)][20],d[20][20];intmain(){inti,j,k,n,smax;scanf("%d",&n);smax=(1<=0;i-=1)for(j=0;j>k&1)&&j!=k)f[i][j]=min(f[i][j],f[1<

注意到\(min\)中的\(f[S\cup\{u\}][u]\)保证了\({u}\)必然在集合\(S\cup\{u\}\)里面,有人可能会说这是废话,但是这说明了在前面的状态中,\(v\)必然在集合\(S\)里面啊!因此对于\(v\)不在集合\(S\)中的情况就不必考虑了。但是,注意当\(S\)为空(程序中变为\(0\))的时候它就不会继续走答案了,也就是说我们要特殊处理一下这种情况。

于是我们得到了\(90\)分代码。

#include#defineINF20000intf[(1<<20)][20],d[20][20];inlineintcmin(inta,intb){returna>j&1)/*添加1*/for(k=0;k>k&1))f[i][j]=cmin(f[i][j],f[1<

让我们再从头开始看,看那个递推式(稍改)。

最开始\(S\)二进制位(位数小于\(N\))全部是\(1\)的时候,仅\(0\)号点为\(0\),其它都是\(INF\)。而有些\(INF\)是可以推到底层的!那什么样的情况满足其\(f\)恒为\(INF\)呢?首先注意到\(f[V][x],x\neq0\)的情况恒为\(INF\),那这个状态又会推到哪里呢?根据递推式:

我们有:

容易得到\(f[S][v]\)必然为\(INF\)(因为\(u\)只有一种可能)。

同理,对于递推式:

故对于任何满足\(\{0\}\inS\)的\(f[S][v]\),它们的值恒为\(INF\)。用二进制表示法来说,只要\(S\And1\)为真,那么就无需考虑。

那么程序就可以“进化”了,从而拿到\(100\)分!

#include#defineINF20000intf[(1<<20)][20],d[20][20];inlineintcmin(inta,intb){returna>j&1)for(k=0;k>k&1))f[i][j]=cmin(f[i][j],f[1<

注意:以上数据均在洛谷测试,均为C++语言。

在状态压缩DP里面,我们也经常会碰到一些“棋盘”题。如果直接暴力搜索的话,会产生“状态爆炸”的尴尬局面,于是我们就需要一个美妙的优化方案——轮廓线优化了。

题目大意:有一块\(M\timesN\)(\(1\leqM,N\leq12\))的长方形牧场,分割的每一块土地都是正方形的(说白了就是棋盘),农夫要在某几格种上牧草或者干脆不种。要求是:不能种在贫瘠的土地上;各个土地上的牧草不能有公共边。土地状况会在输入中给出,求不同的种植方案的个数,答案对\(10^8取模\)。(看你们还怎么用模拟退火)

也许有人会说:啊!这还怎么用状态压缩啊!\(M\timesN\)早就爆炸了啊!(说好的冷静呢)

其实这题有人就这么过了,还写了题解,确实比别的好理解,不过代价就是太慢了。

额哼,不扯了,我们切入正题吧。

其实我们这里没必要搞出这么多状态,我们的方法其实就是逐行递推(逐行动态规划)。转移方程该怎么写呢?也不难,就是根据当前考虑的格子的左边和上面的状态得到当前格的状态。但是要注意不存在的情况及时过滤!于是我们得到递推式:

第一个赋值式表示的是初值(经验所得,下方有答疑);第二个递推式表示的是这个点不被选取的情况;第三个递推式表示这个点被选取的情况。但是需要注意的是,如果这个点被选了,那么第二第三条递推式都要写上,因为农夫可以选择不种(别被细节坑了哦)!

哦,对了,对于某格上面存在草的情况,递推下来的时候要递推到这格不种草的情况,图示:

不能种的情况:

但是仍然要转移过来,不然怎么递推到最后一行去统计呢?如果不清楚的话,下文会提到为什么要在最后一行统计。

您可能会问的问题:

为了追求完美,博主用了滚动数组(也就是数组重复利用,不浪费空间)。

下面是满满的注释的代码,博主满满的爱。

旧洛谷机子上面必然为0ms的代码,别问我为什么。因为新测评机没有0ms了啊!没赶上啊!不过在洛谷IDE(老测评机)测试全为可种草的土\(12\times12\)的数据中,跑出来是0ms的。

还有,这些状态压缩DP只是小部分,后续我可能还会继续更新,比如插头DP等。

请你将下列缺陷填好,使其成为完整的旅行商问题的程序:

#include#define________20000int_[(1<<20)][20],__[20][20];inlineint__________(int______,int_______){return______<_____________:_______;}intmain(){int_____,_______,_________,___________,____;scanf("%d",&___________);____=(1<<___________)-1;for(_____=0;_____<___________;_____+=1)for(_______=0;_______<___________;_______+=1)scanf("%d",&__[_____][_______]);for(_____=0;_____<=____;_____+=1)for(_______=0;_______<___________;_______+=1)_[_____][_______]=________;_[____][0]=0;for(_____=____-1;_____;_____-=2)for(_______=0;_______<___________;_______+=1)if(_____>>_______&1)for(_________=0;_________<___________;_________+=1)if(!(_____>>_________&1))_[_____][_______]=__________(_[_____][_______],_[1<<_________|_____][_________]+__[_______][_________]);int___=________;for(_____=1;_____<___________;_____+=1)___=__________(___,_[1<<_____][_____]+__[0][_____]);printf("%d",___);return0;}别看了,这里没有缺陷,交上去照样AC。

推荐大家看看《挑战程序设计竞赛(第二版)》,讲的也很好噢~感谢参考文献中提到的文献的帮助。除参考部分外,大多数内容(如常数优化,较为通俗的理解,图片等)均为个人智力成果,如需转载,请注明出处,禁止作商业用途传播。最后,感谢各位的阅读。

THE END
1.商推测试的题目和答案.docx该【商推测试的题目和答案】是由【鼠标】上传分享,文档一共【3】页,该文档可以免费在线阅读,需要了解更多关于【商推测试的题目和答案】的内容,可以使用淘豆网的站内搜索功能,选择自己适合的文档,以下文字是截取该文章内的部分文字,如需要获得完整电子版,请下载此文https://www.taodocs.com/p-977030582.html
2.根据外委保运承包商管理办法对保运承包商推行“五个统一”内容是中国公民李某,任职受雇于境内上市公司A,2022年1月10日此前获得A公司限制性股票2000股解禁。该股票每股授予价10元,股票登记日期的当日收盘价16元,本批次解禁当日收盘价14元。下列关于限制性股票个人所得税计算的描述,正确的有()。https://www.shuashuati.com/ti/22448f56b32e4521863fcc2e1cca11a8a1.html
3.商递推题目答案及解析递推数列数字推理数量关系行测公务员递推数列 商递推 ,,,$2$,$6$,$3$,( ) [" "," "," "," 2"] [["A"]] 数列变化趋势平缓,相邻两项之间存在倍数关系,考虑递推商数列。 观察数列发现,,,3=6÷2,规律为第三项=第二项÷第一项,则所求项为3÷6=。 故本题选A。公务员 | 商递推题目答案及解析(完整版) 去刷题 公务员https://www.gaotu.cn/exercise-tools/57/208694914386182144
4.问:怎么买更便宜呢?共需多少钱?请说明理由.题目和参考答案试题答案 分析:由题意可知,这两件商品共需699+910=1609(元).由于甲商场规定:“每满200元减101元.”1609÷200=8…9元,即需花1609-8×101=801元;乙商场规定:“每满101减50元.”1609÷101=15…94元,即需花1609-50×15=859元;801元<859元,所以在甲商场购买便宜,共需801元. 解答:解:699+910=https://m.1010jiajiao.com/xxsx/shiti_id_cbda2b573e18a7906f5fa0eedd6bfe23
5.D.种型号的轿车销售情况最题目和参考答案——青夏教育精英[题目]在“首届中国西部房.车生活文化节 期间.某汽车经销商推出四种型号的小轿车共辆进行展销.型号轿车销售的成交率为.其它型号轿车的参展轿车数的百分比与销售情况绘制如图1和如图2两幅尚不完整的统计图中.下列说法错误的是( )A.参加展销的型号轿车有辆B.型号轿车销售了http://1010pic.com/czsx/shiti_id_00a53d80fc4cd34edb5b3b90cf86ae79
6.推式供应链是以()为核心企业,根据产品的生产和库存情况,有计划地A. 剪压破坏 B. 斜拉破坏 C. 弯曲破坏 , 不发生剪切破坏 D. 斜压破坏 查看完整题目与答案 参考解析: 皮皮学为你提供推式供应链是以()为核心企业,根据产品的生产和库存情况,有计划地把商品推销给客户,其驱动力源于供应链上游制造商的生产。的答案解析 知识点: 欢迎编辑补充 题目纠错 0 发布?https://www.pipixue.com/ti/2d9b1ef502d74e279de9262ba071970b.html
7.网站建设的工作总结13篇2、向服务商申请了域名并成功 信息中心彭亮老师为网站申请了域名,目前学校的网站仍属空间租用,在不久的将来准备为做学校独立服务器,相信经过努力,学校的校园网能够成功建立。 五、开展了大规模的网站信息维护员培训 网站信息维护的培训直接关系着网站是否能有高质量的素材,信息中心高度重视维护员的培训,信息中心逐个通https://mip.wenshubang.com/gongzuozongjie/2972846.html
8.国开(中央电大)专科《市场营销学》网上形考(任务1至4)试题及答案[答案:错] 7.香水制造商设法说服不用香水的妇女使用香水,这是运用了市场渗透策略。[答案:错][答案:产品生命周期的阶段;现实和潜在顾客的状况;产品类型与特点;推或拉的策略] 在以下题目中任选一题,提出自己的观点,进行分析论述。要求:观点明确,论证充分,文字简练。不少于300字。http://www.gjknj.com/duwu/346004.html
9.初一历史试题库11篇(全文)参考答案 初一历史测试题 第7篇 一、选择题 1.唐太宗时期最著名的谏臣是()A.杜如晦 B.房玄龄 C.魏征 D.张玄素 2.我国科举正式诞生是在() A.一、慧眼识真(认真看、仔细想,相信你一定能选出最符合题目要求的一项。每小题3分,共60分) 1、北通涿郡之渔商,南运江都之转输,其为利也博哉!这是https://www.99xueshu.com/w/filevc7ms7gy.html
10.面试经典问题及答案面试是我们整个求职过程中最重要的阶段,成败均决定于你面试时的短短一瞬间的表现。下面是小编整理的面试经典问题及答案,希望能够帮到你。 01面试开始提问 1、请你做一下自我介绍 提示:一般人回答这个问题过于平常:只说姓名、年龄、爱好、工作经验,这些在简历上都有。 https://www.yjbys.com/mianshi/mianshiwenti/4532095.html
11.小学数学四年级奥数知识点及练习题答案【答案】(1)66×35 (2)1234×56 (3)285×35 【例题2】在下面方框中填上适合的数字。 【思路导航】由商的十位是1,以及1与除数的乘积的最高位是1可推知除数的十位是1。由第一次除后余下的数是1,可推知被除数的十位只可能是7、8、9。如果是7,除数的个位是0,那么最后必有余数;如果被除数是8,除数https://www.360doc.cn/article/74961854_1062400170.html
12.面试问题及答案15篇供应商管理体系:(1)正确选择供应商。(2)科学的考评供应商的业绩。(3)保持供应商之间适度竞争。(4)构建与供应商的战略合作伙伴关系 面试问题及答案8 问题一:“请你自我介绍一下” 思路: 1、这是面试的必考题目; 2、介绍内容要与个人简历相一致; 3、表述方式上尽量口语化; 4、要切中要害,不谈无关、无用的http://mip.pincai.com/article/2385908.htm
13.牛客网门头沟学院 测试开发 这个测试一学一个不吱声啊 这个测试你们就学吧,一学一个不吱声 #测试# #公司情报交流地# 转世鼠:赛博电子厂 公司情报交流地 不愿透露姓名的神秘牛友 12-17 14:45 人生第一份实习,平安保险,体验极差 我跟培训的小伙伴们聊过,大家都觉得想走就走,结果我填了离职申请后,主管居然不想让https://www.nowcoder.com/
14.软件项目管理期末选择题复习100题(含答案)在回答下面两道题目时请运用以下信息 BCWS=$2,200 (PV) BCWP=$2,000 (EV) 举例说,你确定使用从未用过的软件版本和软件测试版本是一个你要避免的风险,因此你改变你的计划,使用A.把更多的工作像进度计划后期推,是客户有时间获得现金。 B.消减工作范围并开始收尾工作。 https://blog.csdn.net/bingocoder/article/details/102990658
15.跨界与融合:产业地产的白银时代——第九届中国产业园商务区发展所以,今天我们将聆听行业领导、顶级专家、经济学家和行业大腕,分别从宏观的、产业的、市场的、企业的各个方面进行解读,就京津冀协同中的产业园区、当前房地产市场形势与预测、互联网+产业地产、中国房地产景气指数、产业园区发展趋势、当前房地产市场与企业战略、商业办公建设与运营标准构建、商办地产去库存等热点话题展https://house.hexun.com/2017/9zgcyy/
16.贵州经贸职业技术学院会计金融系采购软件(第三期)竞争性磋商公告(注: 同一供应商可针对三个品目进行投标,但只能中取一个品目.若同一供应商在多个品目中均 为第一候选人,该第一中标候选人只能按品目顺序成为中标人.其余品目顺延第二中标 候选人为中标人,以此类推.支持对当前提交题目分值计算.支持已答,未答,答错,答对题目标识,支持题目特殊标记.支持单题目答案与解析https://ggzy.guizhou.gov.cn/hallweb/hall/attach/nosession/download?attachId=8a8bb7458bfbcd09018c19ac499a2e02