思路:dp[ i ][ 0 ]表示第一个是山谷的方案,dp[ i ][ 1 ]表示第一个是山峰的方案, 我们算dp[ x ][ state ]的时候枚举 x 的位置
x 肯定是山峰, 然后就用组合数算方案就好啦。
卡空间 模数是1e9 不是 109 巨坑。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define PLI pair<LL, int> #define ull unsigned long long using namespace std; const int N = 4200 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; int comb[2][N], cur; int dp[N][2]; int n, p; inline void add(int &a, int b) { a += b; if(a >= p) a -= p; } int main() { scanf("%d%d", &n, &p); dp[0][0] = dp[0][1] = 1; dp[1][0] = dp[1][1] = 1; dp[2][0] = dp[2][1] = 1; comb[0][0] = 1, comb[0][1] = 1; for(int i = 3; i <= n; i++) { cur ^= 1; for(int j = 0; j <= i-1; j++) { if(!j || j == i) comb[cur][j] = 1; else comb[cur][j] = (comb[cur^1][j-1]+comb[cur^1][j])%p; } for(int j = 2; j <= i; j += 2) { int pre = j - 1, suf = i - j; add(dp[i][0], 1ll*comb[cur][pre]*dp[pre][0]%p*dp[suf][0]%p); } for(int j = 1; j <= i; j += 2) { int pre = j - 1, suf = i - j; add(dp[i][1], 1ll*comb[cur][pre]*dp[pre][1]%p*dp[suf][0]%p); } } printf("%d ", (dp[n][0]+dp[n][1])%p); return 0; } /* */