BZOJ 地精部落

2022-05-16 07:32:36 字數 1013 閱讀 2459

僅含一行,兩個正整數 n, p。

僅含一行,乙個非負整數,表示你所求的答案對 p 取餘 之後的結果。

input

4 7output

3對於 20%的資料,滿足 n≤10;

對於 40%的資料,滿足 n≤18;

對於 70%的資料,滿足 n≤550;

對於 100%的資料,滿足 3≤n≤4200,p≤10 9

題意即為求用n個數構成波動序列的方案數。

考慮波動序列有如下性質:

那麼,根據這些性質,我們可以設如下狀態:\(f[i][j]\)表示用了1~i的數,第一項為j的方案數。由於性質2,第一項為山峰對稱一下就可以得到第一項為山谷的方案,因此不妨設j為山峰,最後乘2即可。

下面討論轉移。由性質1,當j與j-1不相鄰時,\(f[i][j]=f[i][j-1]\)。當j-1與j相鄰時,j-1只能為山谷且位於第2位。後面的取值範圍是\([1,j-1]\)和\([j+1,i]\)。同理,第一位為山谷的方案數可以通過性質3由山峰的方案推出,接下來只需要處理值域有空缺的問題。其實我們關心的只是相對的高矮,將區間\([j+1,i]\)整體減一併不影響答案。因此,相當於求用i-1個數0其中第j-1為第一位且為山谷的方案,為\(f[i-1][(i-1+1)-(j-1)]=f[i-1][i-j+1]\)。狀態轉移方程如下:

\[f[i][j]=f[i][j-1]+f[i-1][i-j+1]

\]最後答案為

\[ans=\sum_^f[n][i]

\]注意用滾動陣列優化空間。初始值因為1不可能作為山峰,要從2開始。

#include #include #include #define n 4202

using namespace std;

int n,p,i,j,f[2][n],x;

int main()

int ans=0;

for(i=2;i<=n;i++) ans=(ans+f[x][i])%p;

cout

}

地精部落 dp

description input 僅含一行,兩個正整數 n,p。output 僅含一行,乙個非負整數,表示你所求的答案對p取餘 之後的結果。sample input 4 7sample output 3hint 對於 20 的資料,滿足 n 10 對於 40 的資料,滿足 n 18 對於 70 的...

地精部落 題解

題目描述 輸入格式 僅含一行,兩個正整數 n,p。輸出格式 僅含一行,乙個非負整數,表示你所求的答案對p取餘 之後的結果。樣例樣例輸入 4 7樣例輸出 3資料範圍與提示 對於 20 的資料,滿足 n 10 對於 40 的資料,滿足 n 18 對於 70 的資料,滿足 n 550 對於 100 的資料...

BZOJ1925 地精部落

題目描述 輸入格式 僅含一行,兩個正整數 n,p。輸出格式 僅含一行,乙個非負整數,表示你所求的答案對p取餘之後的結果。樣例樣例輸入 4 7樣例輸出 3資料範圍與提示 對於 20 的資料,滿足 n 10 對於 40 的資料,滿足 n 18 對於 70 的資料,滿足 n 550 對於 100 的資料,...