1925 Sdoi2010 地精部落

2022-05-12 09:56:47 字數 1397 閱讀 3906

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

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

4 73

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

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

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

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

很容易想到乙個比較基本的做法:f[i][j]表示前i個中,最後乙個為j,兩邊比j小,g[i][j]表示,前i個,最後乙個為j,兩邊都比j高;

則f[i][j]=g[i-1][k](0然後發現可以直接定義e[i][j]為前i個最後的數字為1~j,兩邊比j小的情況和,那麼e[i][j]=e[i-1][j]+e[i][j-1]

然後可以發現這是對稱的。。。

即a1,a2,a3,a4,a5是遞增的,則n+1-a1,n+1,a2,n+1-a3,n+1-a4,n+1-a5是遞減的,而且是一一對應的;

則f[i][j]=g[i][i+1-j]

那麼最後答案就需要乘2即可。。

1 #include2 #include3 #include4 #include5 #include6 #include7 #include

8 #include9 #include10 #include11 #include

12#define inf 1000000000

13#define maxn 10000+5

14#define maxm 10000+5

15#define eps 1e-10

16#define ll long long

17#define for0(i,n) for(int i=0;i<=(n);i++)

18#define for1(i,n) for(int i=1;i<=(n);i++)

19#define for2(i,x,y) for(int i=(x);i<=(y);i++)

20#define for3(i,x,y) for(int i=(x);i>=(y);i--)

21#define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)

22using

namespace

std;

23int n,p,x,f[2

][maxm];

24int

read()

27while(ch>='

0'&&ch<='9')

28return x*f;29}

30int

main()

40 printf("

%d",(f[x][n]*2)%p);

41return0;

42 }

view code

bzoj1925 Sdoi2010 地精部落

題目大意 求全排列中鋸齒狀排列的個數。首先進行打表暴力,會發現第乙個元素作為山峰和第乙個元素作為山谷,這兩種方案數是相等的,因此我們只需求出第乙個元素是山谷的方案數再乘2就是答案。做法一 f i 表示i的全排列,第乙個元素時山谷時,鋸齒狀排列的方案數。那麼考慮在i 1的乙個鋸齒狀排列中插入i這個數,...

bzoj1925 Sdoi2010 地精部落

傳送門 我們設f i j 表示前i個數,第i個數排名是j的方案總數。我們可以強制第1個數是山峰。然後我們可以將整個序列高度取反,得到其他的方案數。然後我們發現這樣做的時間複雜度是o n 3 的 加上字首和優化就是o n 2 了 var f array 0.1,0.5005 of longint n,...

bzoj1925 Sdoi2010 地精部落

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