树状DP与状态压缩DP.ppt

  1. 1、本文档共45页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
4.5 TSP 最后的结果是: min( dp[( 1<<n ) – 1][j] ) ( 0 <= j < n ); 技巧:利用2进制,使得一个整数表示一个点集,这样集合的操作可以用位运算来实现。例如从集合i中去掉点j: k = i & ( ~( 1 << j ) ) 或者 k = i - ( 1 << j ) 例题五:走道铺砖问题 题意:给定一个n*m,(n,m<=20)的走道(因为是走道,所以宽度很小,但长度可能很长,保证n*m为偶数),问用1*2的砖块铺满这个走道的方案数有多少。(不用考虑翻转旋转相同的问题,即求的不是本质不同解的数目。) 状态? 转移? 5.2 走道铺砖问题 方法: 用f[i,j]表示从第1行铺到第i行,前i-1行已经全部铺满,且第i行没有横着放的砖,且第i行的铺砖状态为j的二进制数对应的状态,的铺砖方案总数。 1 0 1 0 1 1 第i行 用f[i,43]表示蓝色部分已经确定了的所有铺砖方案数 可以很容易得联想到用f[i-1,0..2m-1]推出f[i,0..2m-1]的思路: f[i,j]=sum{ f[i-1, x] | 0<=x<2m且x&j=0且db(2m-1-x-j)) } x中为1的数位与j中为1的数位全部不相同,且x和j都没有填的位置一定可以只用横着的砖盖满(db函数就是用来做这个判定的,可以预先将0.. 2m-1的db值都求出来并保存在数组中) func db(x): while x>0 do begin a=lowbit(x); x-=lowbit(x); If (x=0) return false; b=lowbit(x); x-=lowbit(x); If (b>a*2) return false; end return true 5.3 走道铺砖问题 0011011110中的所有1就可以用横着的砖盖满,不行。判定可以利用lowbit,每轮取走两位lowbit,如果后取的不是先取的值的两倍,说明两次取的不是相邻的数位。 5.4 走道铺砖问题 最后的结果就是: sum{ f[n, x] | 0<=x<2m且db(2m-1-x) } 计算的时间复杂度则是O(n*22m)。 实际上把f的状态转移方程稍微变一下形式: f[i,j]=sum{ f[i-1, 2m-1-x-j] | 0<=x<2m且db(x)且x&j=0) } 就可以发现,x完全不需要从0一直枚举到2m,只需要枚举有限的若干项在0到2m范围内能通过db判定的x就可以了。 5.5 走道铺砖问题 最后的结果就是: sum{ f[n, 2m-1-x] | 0<=x<2m且db(x) } 计算的时间复杂度则是O(n*y2),其中 y=count{ x | 0<=x<2m且db(x) } 利用排列组合的原理还可以知道: y=C(m-1,1)+C(m-2,2)+…+C(m-m/2,m/2) 当m=10时,y=78,可见其大大小于2m 。 5.6 走道铺砖问题 走道铺砖类似的题也非常多,比如炮兵布阵问题。 还比如本题可以这样改动:砖块不再是1*2这一种规格了,而是有多种占地不超过3*3的砖(像俄罗斯方块);也不再是求铺满走道的方案数了,而是告诉每种规格的砖的美观值,问能放下的砖的美观值的总和的极大值。 不同的变化常常就是进制可能变一下,比如用三进制或四进制来描述状态。 X进制也不仅仅是描述某种排布状态,也可能描述一个集合的状况。 *5.7 走道铺砖其它解法 F[i][k][j], 轮廓线表示法,表示第i-1行已经全部铺满,并且第i行的前k格也已前部铺满,第i+1行的前0到 k-1格及第i行的k到m-1格凸出來的格子全为竖着放(对应2制制数为j) 时的方案数。 转移? *5.8 走道铺砖轮廓线法 f[0][m][j]=0 或1 (由j能否摆得出决定); //整个DP初始 f[i][0][j] = f[i-1][m][j]; //i>0的转移初始 其它转移? *5.9 其它转移, K>0, j的第k-1位为0 If(j的k-2位不为0) f[i][k][j] = f[i][k-1][j^(1<<(k-1))] Else //j的k-2位也為0 f[i][k][j] = f[i][k-1][j^(1<<(k-1))]+ f[i][k-2][j ]; *5.10 其它转移, K>0, j的第k-1位为1 F[i][k][j] = f[i][k-1][j ^ (1<<(k-1))]; 5.11 转移代码 // 初始化 dp[0][m][j] = 1,如果j可以摆得出,否则d

文档评论(0)

369221 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档