ZJOI2009 多公尺諾骨牌

2021-08-26 20:39:03 字數 1590 閱讀 1505

給出一張矩形**,一些地方有障礙物,向其中放1*2的多公尺諾骨牌(不用填滿),要求任何相鄰兩行之間都有至少乙個骨牌橫跨,任何相鄰兩列之間也都至少有乙個骨牌橫跨,求方案數。

為方便,用s(i,j,p,q)表示左上角為(i,j),右上角為(p,q)的子矩形

首先用dp預處理出dp[i][j][p][q]表示s(i,j,p,q)隨意放骨牌的方案數(不考慮行列有無橫跨),然後可以發現dp[i][j][u][q]*dp[i][u+1][p][q]表示在s(i,j,p,q)中第u列和第u+1列之間沒有橫跨骨牌的個數。

因此我們可以用容斥解決列橫跨,而對於行橫跨則不能這樣求解(複雜度更高),我們可以用f[i]陣列表示前i行任何相鄰兩行之間都有至少乙個骨牌橫跨的方案數,這樣就可以得出:

f[x]=t[1][x]-∑i=

2x

\sum_^x

∑i=2x​

f[i-1]*t[i][x]

其中t[i][j]表示i行到j行不考慮行橫跨的方案數。

將兩種橫跨的求法結合起來,即可得到答案。

#include

#include

#define ll long long

#define n 20

#define mn 40000

#define m 19901013

using

namespace std;

ll m,n,dp[n]

[n][n]

[n],tmp[2]

[mn]

,f[n]

,num[n]

,top,ans;

char str[n]

;bool mm[n]

[n];

inline ll ask

(ll u,ll v)

inline

void

work

(ll w,ll u,ll v)if(

!mm[i]

[j])

} now=nxt;

} dp[w]

[u][i-1]

[v]=tmp[now]

[zt];}

}int

main()

}for

(i=1

; i<=n; i++)}

} tot=(1

<<

(n-1))

-1;for

(i=0

; i<=tot; i++

) num[

++top]

=n;for

(d=1

; d<=m; d++)if

(u==

1) f[d]

=t;else f[d]

-=t*f[u-1]

%m,f[d]

%=m;}}

f[m]

=(f[m]

+m)%m;

if(top&

1) ans-

=f[m]

;else ans+

=f[m]

; ans%

=m;}

cout<<

(ans+m)

%m;}

多公尺諾骨牌

100張多公尺諾骨牌整齊地排成一列,按順序編號為1 2 3 4 99 100。第一次拿走所有的奇數字置上的骨牌,第二次再從剩餘的骨牌中拿走所有奇數字置上的骨牌,依次類推,請問最後剩下的一張骨牌的編號是多少 a.48 b.50 c.52 d.64 正確答案 d.答對了嗎?答對了嗎?答對了嗎?第一次拿走...

多公尺諾骨牌

現有n塊 多公尺諾骨牌 s1,s2,s3,sn水平放成一排,每次骨牌si包含左右兩個部分,每個部分賦予乙個非負整數值,如下圖所示為包含6塊骨牌的序列.骨牌可做180度旋轉,使得原來在左邊的值變到右邊,而原來右邊的值移到左邊,假設不論si如何旋轉,l i 總是儲存si左邊的值,r i 總是儲存si右邊...

多公尺諾骨牌

在課堂上,我們分析了棋盤覆蓋問題,同學們也看了我的程式執行的情況,今天我們來看一下另外乙個覆蓋問題。今天的問題是這樣的 用n個2x1的矩形 這種矩形我們以後稱之為骨牌或多公尺諾 覆蓋2xn的棋盤,有多少種不同的覆蓋法?input 本問題有多組測試資料,對於每一組測試資料,輸入只有一行n 意義如上所述...