大家說他是卡特蘭數,其實也不為過,一開始只是用卡特蘭數來推這道題,一直沒有懟出來,後來發現其實卡特蘭數只不過是一種組合數學,我們可以退一步直接用組合數學來解決,這道題運用組合數的思想主要用到補集與幾何法。
假設以矩形左下角為座標原點,(以下所說路徑均滿足只能向右或向上走),我們假設原矩陣為a,那麼他關於l(y=x+1),對稱矩形就是b(黑色),那麼出現了c矩陣,他的長為n+1,寬為m-1,易知從(0,0)到(n,m)(a右上角)的路徑(在矩形a內)的種數就是c(n+m,m),然後我告訴你從(0,0)到(m-1,n+1)(c右上角)的路徑(在矩形c內)種數c(n+m,m-1),就是原矩陣中不合法路徑個數,你不信很正常.....
那麼讓我們想一下。從(0,0)到(n,m)的不合法路徑(在矩形a內)一定滿足若干次碰到了l與a圍成的三角型的邊界之一——l在a內部分,然後在最後一次碰到後離開並駛向(n,m),從(0,0)到(m-1,n+1)的路徑(在矩形c內)均滿足若干次碰到了l與a圍成的三角型,然後在最後一次碰到後離開並駛向(m-1,n+1),再然後我們發現在「離開」之前的走法滿足以上兩種路徑可以吻合,那麼「離開「之後呢——他離開時一定最後與l交於一點,那麼我們發現在l上的任意整點(在a內部分)與(n,m)和(m-1,n+1)分別作為兩個對角點形成的矩形全等,於是從一角到另一角的方案一一對應,於是證畢。
#include #includeconst
int p=10000
;struct
bigint
inline friend bigint
operator -(bigint a,bigint b);
inline friend bigint
operator * (bigint a,int
b); inline
void
operator -= (bigint b)
inline
void
operator *= (int b)
inline
void
print();
}ans1,ans2;
inline
void
bigint:: print()
inline bigint
operator -(bigint a,bigint b)
while(a.a[a.a[0]]==0)a.a[0]--;
returna;}
inline bigint
operator * (bigint a,int
b)int
n,m;
int prime[p+10],len,mini[p+10
];bool isnot[p+10
];inline
void
get_prime()
}}intsize[p];
intmain()
for(int i=1,x;i<=m;++i)
for(int i=1;i<=len;++i)
while
(size[i])
ans1*=prime[i],--size[i];
for(int i=n+m,x;i>n+1;--i)
for(int i=1,x;ii)
for(int i=1;i<=len;++i)
while
(size[i])
ans2*=prime[i],--size[i];
ans1-=ans2;
ans1.print();
return0;
}
bzoj1008 越獄 組合數學
監獄有連續編號為1 n的n個房間,每個房間關押乙個犯人,有m種宗教,每個犯人可能信仰其中一種。如果相鄰房間的犯人的宗教相同,就可能發生越獄,求有多少種狀態可能發生越獄 輸入兩個整數m,n.1 m 10 8,1 n 10 12 可能越獄的狀態數,模100003取餘 2 366種狀態為 000 001 ...
BZOJ 1008 越獄(組合數學)
思路 首先全部情況有m n種,不滿足題意的情況有m m 1 n 1 種情況,然後快速冪就好啦 include includeusing namespace std define ll long long define mod 100003 ll powmod ll a,ll b return ans...
BZOJ 1008 越獄(組合數學)
description 監獄有連續編號為 1.n 1.n的 n n 個房間,每個房間關押乙個犯人,有 m role presentation style position relative m m種宗教,每個犯人可能信仰其中一種。如果 相鄰房間的犯人的宗教相同,就可能發生越獄,求有多少種狀態可能發生...