題目
問有多少個的排列對於在的情況下都滿足或
分析
思維好題
首先考慮性質,
- 對於不相鄰的兩個數,可以互換
- 合法的排列翻轉依舊合法
- 把合法排列每個數都變成,排列依舊合法
考慮dp,設表示選擇,第一個數爲,且第一個數大於第二個數的方案,所以最後答案要乘2
因爲和在不相鄰時可以互換,所以可以由轉移而來,接着如果和相鄰,那麼也就轉換成選擇,第一個數爲,且第一個數小於第二個數的方案,但是這和定義不符,考慮轉換成選擇,第一個數爲,且第一個數大於第二個數的方案,因爲如果進行第三條性質,那麼原來大的反而小,初始化
綜上所述,
代碼
#include <cstdio>
#define rr register
using namespace std;
int n,mod,dp[2][4211],ans;
inline signed mo(int x,int y){return x+y>=mod?x+y-mod:x+y;}
signed main(){
scanf("%d%d",&n,&mod),dp[0][2]=1;
for (rr int i=3;i<=n;++i)
for (rr int j=2;j<=i;++j)
dp[i&1][j]=mo(dp[i&1][j-1],dp[(i&1)^1][i-j+1]);
for (rr int i=2;i<=n;++i) ans=mo(ans,dp[n&1][i]);
return !printf("%d",mo(ans,ans));
}