题目:http://poj.org/problem?id=1739
这种题新手必须仔细钻研大牛们的代码!!!!这一点很重要
大体上与陈丹琪的例题差不多,就是n*m的矩阵求从左下角到右下角的一条满足遍历除障碍外的所有格点的路的方案数。
首先膜拜陈丹琪的论文:http://wenku.baidu.com/view/f49801155f0e7cd18425368e.html
定义dp[l,i,j]为l行以上(包括l行[1,1]到[l,i])中已构成的所有连通块构成连通的方案数(j为当前轮廓线压缩后的状态,用括号表示法)。
1为(,2为),0为无括号,三进制。
十进制数num在三进制中第k位是 num div power(3,k-1) mod 3
类似于二进制取第k位 num and power(2,k-1)>>k-1 = num div power(2,k-1) mod 2 = num>>k-1 mod 2
dp[0,0,0]=1
(注意我的l,i是从0开始到n-1或m-1)
转移就很简单了:引用梁盾大牛的讲述:
1.这个方格上面没有插头,那么也就是意味着路径在这里打了个弯,因此生成一左一右两个插头:
2.这个方格上方或左方有一个插头,那么他可以继续延续,插在下方或者是右方:
3.这个方格上有一右一左两个插头,直接删除合并:
4.这个方格上游一左一右两个插头,直接pass,因为用他转移的话路径将会出现不连通的环;
5.这个方格上有两个左插头,同样意味着路径在这里打了个弯,我们需要把这两个左插头删掉,并且把较靠右的左插头所匹配的右插头改成左插头(开始想成把右边第一个右插头删掉,无限WA。。):
6.这个方格上有两个右插头,同上:
http://blog.csdn.net/jasonzhu8/archive/2010/08/01/5779518.aspx
有一个特殊情况就是如果i=m 注意不是m-1(m-1时不用特殊处理)
且j div power(3,m)=0 时
就要换行,当前为dp[l,i,j],则转移为:dp[l+1][0][j*3]:=dp[l+1][0][j*3]+dp[l][i][j]
详见代码(313MS,神奇的比盾爷的程序快(800MS))
再次注意虽然我说十进制数num在三进制中第k位是 num div power(3,k-1) mod 3 但由于我的行列是从0开始
所以我取位写成了num div power(3,k) mod 3