[BZOJ1925][SDOI2010]地精部落(DP)

題意

傳說好久之前,大地上居住着一種神祕的生物:地精。 地精喜歡住在連綿不絕的山脈中。具體地說,一座長度爲 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;
}
相關文章
相關標籤/搜索