P2467 [SDOI2010]地精部落
首先,三个性质:
First: 在一个波动数列中,若两个 i 与 i+1 不相邻,那么我们直接交换这两个数字就可以组成一个新的波动数列;
second:把波动数列中的每个数字Ai 变成 (N+1)-Ai 会得到另一个波动数列,且新数列的山峰与山谷情况相反;
3 波动序列有对称性
#include<iostream>
#include<cstdio>
using namespace std;
const int N=5e3+7;
int n,ans,p;
int f[3][N];
int main(){
scanf("%d%d",&n,&p);
f[0][2]=1;
for(int i=3;i<=n;i++){
for(int j=2;j<=i;j++){
f[i&1][j]=1LL*(1LL*f[i&1][j-1]+f[(i-1)&1][i-j+1])%p;
}
}
for(int i=2;i<=n;i++){
ans=(ans+f[n&1][i])%p;
}
cout<<(ans<<1)%p;
}