SDOI2010 地精部落

2022-03-25 18:51:02 字數 1325 閱讀 9890

這道題是一道$dp$題,思維難度比較大。

題意:先定義波形陣列:滿足當$i$全為奇數或偶數時,$a[i]>a[i-1]$且$a[i]>a[i+1]$。

求$n$的全排列中有多少個符合波形陣列。

我們記錄狀態為$f[i][j][0/1]$,$i$為剩下$i$個數,$j$表示有$j-1$個數小於剛剛選擇的數,當第$3$個下標為$0$時,表示這是山谷,為$1$則說明是山頂。

推理知道$f[i][j][0]$能影響$f[i-1][j..i][1]$,$f[i][j][1]$能影響$f[i-1][1..j-1][0]$。

最後求$f[0][1][0]+f[0][1][1]$的值即可。

此時時間複雜度為$o(n^3)$,空間為$o(n^3)$。

但是過不了。。

考慮將轉移方程變化下,把刷表改成填表,就發現$f[i][j][1]=\sum_^jf[i+1][x][0]$,$f[i][j][0]=\sum_^f[i+1][x][1]$,然後又發現可以在填表的過程中順便求下$\sigma$,於是就優化到了$o(n^2)$。

而空間可以通過滾動陣列優化掉一維。

1 #include 2

3using

namespace

std;45

#define re register

6#define rep(i, a, b) for (re int i = a; i <= b; ++i)

7#define repd(i, a, b) for (re int i = a; i >= b; --i)

8#define maxx(a, b) a = max(a, b);

9#define minn(a, b) a = min(a, b);

10#define ll long long

11#define inf (1 << 30)

1213 inline int

read()

1920

const

int maxn = 4200 + 10;21

22int f[2][maxn][2], n, p, cur = 1;23

24int

main()

39 v = f[cur^1][i+2][1

];40 repd(j, i+1, 1

) 44}45

46 printf("

%d", (f[cur][1][0] + f[cur][1][1]) %p);

4748

return0;

49 }

這道題還可以用數學統計下手推方程。

SDOI2010 地精部落

求1 n的全排列數目,使得對於 i geq 3 a a 的大小關係與 a a 的大小關係不同 題目還有另外一種格式 求一種全排列,使得這個排列要麼滿足奇數項的高度比相鄰位置都大,要麼滿足偶數項的高度比相鄰位置都大.設 dp 表示用了前 i 個數字,a 1 j 且 a 1 a 2 時的方案數 有乙個神...

SDOI2010 地精部落

sdoi2010 地精部落 僅含一行,兩個正整數 n,p。僅含一行,乙個非負整數,表示你所求的答案對p取餘 之後的結果。4 7對於 20 的資料,滿足 n 10 對於 40 的資料,滿足 n 18 對於 70 的資料,滿足 n 550 對於 100 的資料,滿足 3 n 4200,p 109 我覺得...

SDOI2010 地精部落

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