有乙個n*m的棋盤,現在用1*2的骨牌去覆蓋,問有多少種不同方法可以將這個棋盤全部覆蓋。
1、狀態壓縮dp
列舉相鄰兩行的狀態進行匹配轉移 複雜度o( n * (2^m)^2 )
poj 2663:
#include // poj 2663.cpp
#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;
#define rep(i,j,k) for (int i=j;i<=k;i++)
#define rrep(i,j,k) for (int i=j;i>=k;i--)
#define clean(x,y) memset(x,y,sizeof(x))
#define ll long long
#define ull unsigned long long
#define inf 0x7fffffff
#define mod %100000007
int n;
ll dp[35][8];
bool fit(int x1 , int x2 , int uplim)
int main()
if ( n & 1 )
clean(dp,0);
dp[1][0] = dp[1][3] = dp[1][6] = 1;
int uplim = 1<<3;
rep(i,2,n)
rep(j,0,uplim-1)
rep(k,0,uplim-1)
if( fit(j,k,uplim-1) ) dp[i][j]+=dp[i-1][k];
cout<
#include //hiho 1161.cpp
#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;
#define rep(i,j,k) for (int i=j;i<=k;i++)
#define rrep(i,j,k) for (int i=j;i>=k;i--)
#define clean(x,y) memset(x,y,sizeof(x))
#define ll long long
#define ull unsigned long long
#define inf 0x7fffffff
#define mod 12357
int uplim;
int n,k;
struct node
void zhuanyi()
void dfs( int x , int y , int col ) //構造上一行狀態為x,當前行狀態為y x->y的轉移矩陣
dfs( x<<1|1 , y<<1 , col + 1 ); //第col列不放,所以上一行已經被填充過了,而當前行還是空的
dfs( x<<1 , y<<1|1 , col + 1 );//col列豎著放,上一行肯定沒有被填充,而放過之後當前行會被填充
if ( col + 2 <= k ) dfs( x<<2|3 , y<<2|3 , col + 2 );//在當前行的col列和col+1列橫著放
}};node multi( node &x , node &y ) //矩陣乘法
return ans;
}int main()
cout<
3、掃瞄線
複雜度 o( n*m*2^m )
uva 11270
#include //uva 11270.cpp
#include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;
#define rep(i,j,k) for (int i=j;i<=k;i++)
#define rrep(i,j,k) for (int i=j;i>=k;i--)
#define clean(x,y) memset(x,y,sizeof(x))
#define ll long long
#define ull unsigned long long
#define inf 0x7fffffff
#define mod %100000007
const int maxn = 13;
ll dp[2][1<1 && !( k & 1<<(m-1) ) ) //豎著放
update( k , k<<1|1 , cur );
if ( j > 1 && ( k & 1<<(m-1) ) && !( k & 1 ) ) //橫著放
update( k , (k<<1)^(uplim+1)^3 , cur );}}
printf("%lld\n",dp[cur][uplim]);
}int main()
return 0;
}3、狀態壓縮轉移
列舉相鄰兩行的狀態進行匹配轉移 複雜度o( n * (2^m)^2 )
poj 2663
#include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std;
#define rep(i,j,k) for (int i=j;i<=k;i++)
#define rrep(i,j,k) for (int i=j;i>=k;i--)
#define clean(x,y) memset(x,y,sizeof(x))
#define ll long long
#define ull unsigned long long
#define inf 0x7fffffff
#define mod %100000007
int n;
ll dp[35][8];
bool fit(int x1 , int x2 , int uplim)
int main()
if ( n & 1 )
clean(dp,0);
dp[1][0] = dp[1][3] = dp[1][6] = 1;
int uplim = 1<<3;
rep(i,2,n)
rep(j,0,uplim-1)
rep(k,0,uplim-1)
if( fit(j,k,uplim-1) ) dp[i][j]+=dp[i-1][k];
cout<
骨牌覆蓋問題
骨牌覆蓋問題,就是用 1x2 大小的骨牌,鋪設乙個給定大小的乙個矩形區域,要求必須鋪滿,且不可以超出邊界。問總的鋪設方案數字多少?這一類問題就是骨牌覆蓋問題。不同規模的資料有不同的方法。下面來看看最簡單的 2 n 區域裡面的鋪設方法數。n 0,一種 n 1 為一種 n 2,兩種 n 3,5種 較為容...
骨牌覆蓋問題
骨牌覆蓋問題 用1 2骨牌完美覆蓋n m棋盤,求方案數 如果骨牌橫著放,只能兩個橫著的骨牌摞在一起 如果豎著放,恰好佔一列 所以dp i dp i 1 dp i 2 即斐波那契數列 可以想到乙個遞推式 f n a2 f n 2 a4 f n 4 a6 f n 6 an f 0 ai i是偶數 是未知...
骨牌組成矩形問題
演算法 遞推 數學綜合 題目大意 有t資料,給定乙個2 n的矩陣,只能利用1 2和2 2的骨牌,讓你去組成2 n的矩陣,問有多少種組成方法。分析 從題目大意上不難看出,本題是一道遞推題目,由前面的組成方案可以推得後面的組成方案,具體推法如下 1 當前的2 n的矩陣可以拆分成2 n 1 1 2的或者是...