写在前面
首先,讲题时因为自己本身也没想到正解,所以匆匆忙忙学了一下别人的方法,自己也没完全理解,耽误了大家一些时间,请见谅,接下来会详细讲解第三题,如有任何问题可以在下方评论,或直接在oj上问我。
首先讲讲第三题:
做第三题前首先要明白xor and or三个位运算操作的性质.
xor:相同为0,否则为1.
and:两数为1则为1,否则只要有一个0就是0.
or:两数为0则为0,否则只要有一个1就是1.
搞懂这三个最最基本的位运算操作符后,就可以讲状压DP了.
首先要弄懂我们到同一个点所经过同一种路线那么肯定只选一个最优值.
那很容易就想到把前面经过的点的状态处理一下,做成一个n维的数组,但这样子很明显是行不通的.
所以,我们可以把到一个点之前的所有经过的点记录一下,对于之前经过的每个点只有走或没走过两种状态(0或1),那么这些所有点所表示的数连在一起很明显就是一个二进制数.
那么我们把这个二进制数压成十进制就可以方便操作了
(以下所有操作视状态为1的表示没选,为0的表示已选).
我们设f[i][j]表示当前走到第j个点,之前所经过的点所表示的状态压成十进制数为i的最小值.
则我们除了枚举i,j,还要枚举j是从哪个得来的,设其为k.
那么对于枚举的j,k(j<>k),必须满足——
i and (1 shl (j-1))=1 shl (j-1)
i and (1 shl (k-1))=1 shl (k-1)
或也可表示为满足——
i or (1 shl (j-1))=i
i or (1 shl (j-1))=i
这四个式子是两两等价的,至于为什么就请自己探讨一下吧.
满足这条件之后很明显可以推出状态转移方程为:
f[i,j]:=min{f[i xor (1 shl (j-1)),k]}
初值是f[1 shl (i-1),i]=0,其余为∞.
最后答案就为min{f[1 shl n-1,i]}(这个所表示的应该是当前我从第i个点出发选数,开始状态为所有都没选,于是从第i个点开始,往下选剩下点的最优值)
T1:
数学方法,会勾股定理的再加个zz优化就可过.
T2:很明显的bfs,太水.
T3:就是一道搜索然后随便处理一下的题目.
不明白某些人,为什么要把自己的方法说成打表?很光荣?其次,你也得先明白什么叫做打表!