傳說好久之前,大地上居住着一種神祕的生物:地精。 地精喜歡住在連綿不絕的山脈中。具體地說,一座長度爲 N 的山脈 H可分 爲從左到右的 N 段,每段有一個獨一無二的高度 Hi,其中Hi是1到N 之間的正 整數。 若是一段山脈比全部與它相鄰的山脈都高,則這段山脈是一個山峯。位於邊 緣的山脈只有一段相鄰的山脈,其餘都有兩段(即左邊和右邊)。 相似地,若是一段山脈比全部它相鄰的山脈都低,則這段山脈是一個山谷。 地精們有一個共同的愛好——飲酒,酒館能夠設立在山谷之中。地精的酒館 不論白天黑夜老是人聲鼎沸,地精美酒的香味能夠飄到方圓數裏的地方。 地精仍是一種很是警覺的生物,他們在每座山峯上均可以設立瞭望臺,並輪 流擔當瞭望工做,以確保在第一時間得知外敵的入侵。 地精們但願這N 段山脈每段均可以修建瞭望臺或酒館的其中之一,只有知足 這個條件的整座山脈纔可能有地精居住。 如今你但願知道,長度爲N 的可能有地精居住的山脈有多少種。兩座山脈A 和B不一樣當且僅當存在一個 i,使得 Ai≠Bi。因爲這個數目可能很大,你只對它 除以P的餘數感興趣。c++
DPspa
可是思惟難度大code
借鑑別人的blog
bzoj限空間,要滾存it
#include<bits/stdc++.h> using namespace std; const int N=4210; int C[2][N],f[N],P,n; int main() { scanf("%d%d",&n,&P); C[0][0]=C[1][0]=f[0]=1; for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) { if(j&1) (f[i]+=1ll*f[j-1]*f[i-j]%P*C[(i-1)&1][j-1]%P)%=P; C[i&1][j]=(C[(i-1)&1][j]+C[(i-1)&1][j-1])%P; } printf("%d\n",2ll*f[n]%P); return 0; }