铺瓷砖问题 (状态压缩轮廓线动态规划) (二)

作者: Phill King

邮箱: [email protected]

原创文章,转载请注明出处。

在之前的文章 铺瓷砖问题(一)中介绍了状态压缩动态规划的方法,但是时间复杂度较高。在此介绍一下轮廓线动态规划算法,可以更快的解决问题。

  • 定义状态

依然设行数为N,列数为M.

在前文我们用整行来定义状态,然后对相邻两行的状态进行转移。 在此我们定义以当前格结尾的M个格子为状态的范围。如下图所示:

铺瓷砖问题 (状态压缩轮廓线动态规划) (二)_第1张图片

  • 状态转移

这样定义状态虽然数量增多了,但好处是状态转移关系非常的简单,只有三种可能。因此总的复杂度依然可以降低很多。

状态转移的三种情况见下图:

铺瓷砖问题 (状态压缩轮廓线动态规划) (二)_第2张图片

转换1:  上一个状态最高位为1, 当前格可以选择不放。

              newState = (State<<1)^(1<

转换2:上一个状态最高位为0, 必须竖放

             newState = (State<<1)^1    // 最低位设置为1

转换3: 上一格状态最高位为1,且最低位为0, 可以横放。

             newState = (State<<1)^(1<

 

  • 代码:
long long int  getCoverWays(int rows, int cols){
	// the size of area must be even.
	if((rows*cols)%2 != 0){
		return 0;
	}
	// make sure columns is smaller;
	if(cols>rows){
		swap(rows,cols);
	}

	const int STATE_MAX = 1< > dp(2, vector(STATE_MAX,0));
    // assume the initial state is all 1
	int cur = 0;
	dp[cur][STATE_MAX-1] = 1;
	for(int i=0; i

 

基于轮廓线的动态规划方法将时间复杂度从N*4^{M}降低到N*M*2^{M}, 并且状态转移关系更加简单。

 

 

 

 

 

 

 

你可能感兴趣的:(铺瓷砖问题 (状态压缩轮廓线动态规划) (二))