求在$[1,n]$的排列中是波動序列的數量。
當我們對波動序列$a$進行以下操作時,得到的新序列仍然是個波動序列:
若$a_i = a_j+1且|j-i|>1$,將$a_i,a_j$交換。
將波動序列上下翻轉(也就是$\forall a_i, a_i\rightarrow n-a_i +1$)。
將波動序列左右翻轉(也就是$\forall a_i, a_i\rightarrow a_$)。
另外有性質1:對於任意乙個長度為$n$,數值兩兩不同,且數值取值範圍固定但不限於$[1,n]$的波動序列$a$,它的種類數與長度為$n$,數值取值等於$[1,n]$的序列的種類數是相同的。
由操作3我們可以想到:若我們規定每個波動序列的第乙個數字都是山峰,那麼最後我們的結果就是這些波動序列的數量*2,所以我們要用$j$表示第乙個數字為$j$且它為山峰;因為乙個波動序列的每乙個子串行都滿足性質1,所以我們要用$i$來表示波動序列長度為$i$,且數值取值範圍等於$[1,i]$的結果。$f$表示這樣的種類。狀態$f(i,j)$就出來了。
由序列中元素$a_1$與$a_2$的關係分兩種情況。
所以最後的遞推式為$f(i,j)=f(i,j-1)+f(i-1,i-j+1)$
#include #include #include using namespace std;#define f(i, j) dp[(i) & 1][j]
const int max_n = 5000;
long long dp[2][max_n], p;
int n;
long long dp()
long long ans = 0;
for (int i = 2; i <= n; i++)
ans = (ans + f(n, i)) % p;
return (ans * 2) % p;
}int main()
P2467 SDOI2010 地精部落
傳說很久以前,大地上居住著一種神秘的生物 地精。地精喜歡住在連綿不絕的山脈中。具體地說,一座長度為n的山脈h可分為從左到右的n段,每段有乙個獨一無二的高度hi,其中hi是1到n之間的正整數。如果一段山脈比所有與它相鄰的山脈都高,則這段山脈是乙個山峰。位於邊緣的山脈只有一段相鄰的山脈,其他都有兩段 即...
P2467 SDOI2010 地精部落 dp
求長度為n nn的波動序列的個數。我們先考慮第乙個是上公升的,然後乘2即可。設f i,jf fi,j 表示填1 i 1 sim i 1 i個,最前面的是j jj的個數。然後我們只要是1 i j 1 1 sim i j 1 1 i j 1,當然可以填i ii那麼一定可以填i 1 i 1i 1,所以有遞...
Luogu2157 SDOI2009 學校食堂
link 給定 n 個學生的口味和忍耐度,若前一道菜的對應的口味是a,這一道為b,則做這道菜所需的時間為 a b a b 而做第一道菜是不需要計算時間的.每個學生可以忍耐忍耐度以下的人在他前面插隊買飯 求最小的做飯時間 n le 1000,b i le 8 令 f 表示第 i 個人前面的狀態是 s ...