51nod 1033 骨牌覆蓋 V2

2021-08-18 07:55:24 字數 1499 閱讀 7822

題意:

1033 骨牌覆蓋 v2

基準時間限制:1 秒 空間限制:131072 kb 分值: 320 

難度:7級演算法題

在m*n的乙個長方形方格中,用乙個1*2的骨牌排滿方格。問有多少種不同的排列方法。(n <= 5)

例如:3 * 2的方格,共有3種不同的排法。(由於方案的數量巨大,只輸出 mod 10^9 + 7 的結果)

2個數m n,中間用空格分隔(2 <= m <= 10^9,2 <= n <= 5)
output

輸出數量 mod 10^9 + 7
input示例

2 3
output示例

3
sol:

不用維護聯通分量資訊,只需要維護輪廓線上的m個格仔是否填充。

由於n很大,必須使用矩陣快速冪。

可以看到按行轉移形式是固定的,與具體第幾行無關,所以可以求出轉移一整行後的轉移矩陣,然後進行快速冪。

矩陣中某個狀態k的貢獻可以讓其為1,其他狀態初值為0,逐格轉移之後各狀態h計數的值就是轉移矩陣 c(k,h)的值了。

code:

#include #include #include #include #include using namespace std;

const int maxn = 1 << 5;

typedef long long ll;

const int mod = 1e9+7;

using namespace std;

ll dp[6][maxn];

typedef vectorvec;

typedef vectormat;

mat mul(mat &a, mat &b)

}return c;

}mat pow(mat a, ll n)

return b;

}int main()

int s_l = 1 << (j - 1);

int p_l = k & s_l;

if (p_u == 0 && p_l == 0)

else if (p_u > 0 && p_l > 0)

else if (p_u > 0 && p_l == 0)

else if (p_u == 0 && p_l > 0)}}

for (int i = 0; i < maxs; i++)

}mat a(1, vec(maxs));

a[0][maxs - 1] = 1;

c = pow(c, n);

a = mul(a, c);

ll ans = 0;

ans=a[0][maxs-1];

printf("%lld\n",ans);

return 0;

}

51nod 1033骨牌覆蓋 V2

矩陣乘法題 就是狀壓一下一列的狀態然後預處理出某兩種狀態的轉移的方案數 然後構造乙個矩陣a i j 表示i的狀態到j的狀態的條數 然後直接矩陣乘法就可以了 include include include includeusing namespace std const int mod 1000000...

51nod 1033 骨牌覆蓋 V2

思路 狀態壓縮dp 矩陣快速冪 對於每行最多只有5列,因此可以列舉出它們的全部狀態 0 1 1.由於是1x2的骨牌,則二進位制數11,110是合法的,1,10是不合法的,那麼其合法的狀態只有d 2.對於第i行的狀態只與第i 1行的狀態有關,那麼對於第i 1行的狀態a中二進位制位為0的就必須要在第i行...

51nod 1033 骨牌覆蓋 V2(矩陣快速冪)

思路 這類題主要的難點就在於狀態的轉移,可以先看看這道題 骨牌覆蓋問題 三 中的提示 dp i j 表示從狀態i轉換成狀態j共有多少種方法 二進位制下的01表示骨牌是否覆蓋 則m行的排法就是dp m 1 的值 第0行的狀態為0,第m行的狀態為 1 n 1,則需進行m 1次dp dp dp 因此,我們...