1. 程式人生 > >Codevs 1523 地精部落

Codevs 1523 地精部落

all for 裏的 nbsp log hint include pre cst

1523 地精部落

省隊選拔賽

時間限制: 1 s 空間限制: 256000 KB 題目等級 : 大師 Master 題目描述 Description

傳說很久以前,大地上居住著一種神秘的生物:地精。
地精喜歡住在連綿不絕的山脈中。具體地說,一座長度為 N 的山脈 H可分為從左到右的 N 段,每段有一個獨一無二的高度 Hi,其中Hi是1到N 之間的正整數。
如果一段山脈比所有與它相鄰的山脈都高,則這段山脈是一個山峰。位於邊緣的山脈只有一段相鄰的山脈,其他都有兩段(即左邊和右邊)。

類似地,如果一段山脈比所有它相鄰的山脈都低,則這段山脈是一個山谷。
地精們有一個共同的愛好——飲酒,酒館可以設立在山谷之中。地精的酒館不論白天黑夜總是人聲鼎沸,地精美酒的香味可以飄到方圓數裏的地方。
地精還是一種非常警覺的生物,他們在每座山峰上都可以設立瞭望臺,並輪流擔當瞭望工作,以確保在第一時間得知外敵的入侵。
地精們希望這N 段山脈每段都可以修建瞭望臺或酒館的其中之一,只有滿足這個條件的整座山脈才可能有地精居住。
現在你希望知道,長度為N 的可能有地精居住的山脈有多少種。兩座山脈A和B不同當且僅當存在一個 i,使得 Ai≠Bi。由於這個數目可能很大,你只對它除以P的余數感興趣。

輸入描述 Input Description

輸入僅含一行,兩個正整數 N,P。

輸出描述 Output Description

輸出僅含一行,一個非負整數,表示你所求的答案對P取余之後的結果。

樣例輸入 Sample Input

4 7

樣例輸出 Sample Output

3

數據範圍及提示 Data Size & Hint

共有10 種可能的山脈,它們是:
1324 1423 2143 2314 2413

3142 3241 3412 4132 4231



【數據規模和約定】
對於 20%的數據,滿足 N≤10;
對於 40%的數據,滿足 N≤18;
對於 70%的數據,滿足 N≤550;
對於 100%的數據,滿足 3≤N≤4200,P≤109。

/*
    f[i][j]第一位為[1,j]且第一位下降的1~i的合法排列數,先給出結論:f[i][j] = f[i][j – 1] + f[i – 1][i – j]
    首先是要加上[1,j – 1]的合法排列數,然後考慮j開頭的第一位下降合法排列數
    這個就是求以[1,j]開頭的1~n-1的第一位上升合法排列數(這個應該可以YY一下吧..)
    但是第一位上升的合法排列數我們是沒有算的,但註意到第一位上升和第一位下降具有對稱性
    所以求以[1,j]開頭的1~n-1的第一位上升合法排列數就是f[i – 1][i – j]
    然後如果開[4200][4200]的int的話正好會被卡掉,所以必須滾動數組..
*/
#include<iostream>
#include<cstdio>
using namespace std;
int n,p;
int dp[2][5000];
int main(){
    scanf("%d%d",&n,&p);
    int x;
    dp[1][1]=1;
    for(int i=2;i<=n;i++){
        for(int j=1;j<=i;j++){
            x=i&1;
            dp[x][j]=dp[x][j-1]+dp[x^1][i-j];
            dp[x][j]%=p;
        }
    }
    printf("%d",(long long)(dp[n&1][n]*2)%p);
    return 0;
}

Codevs 1523 地精部落