bzoj 1925 dp

时间:2020-12-14 13:48:27

思路: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 = + ;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + ;
const double eps = 1e-; int comb[][N], cur;
int dp[N][];
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[][] = dp[][] = ;
dp[][] = dp[][] = ;
dp[][] = dp[][] = ;
comb[][] = , comb[][] = ;
for(int i = ; i <= n; i++) {
cur ^= ;
for(int j = ; j <= i-; j++) {
if(!j || j == i) comb[cur][j] = ;
else comb[cur][j] = (comb[cur^][j-]+comb[cur^][j])%p;
}
for(int j = ; j <= i; j += ) {
int pre = j - , suf = i - j;
add(dp[i][], 1ll*comb[cur][pre]*dp[pre][]%p*dp[suf][]%p);
}
for(int j = ; j <= i; j += ) {
int pre = j - , suf = i - j;
add(dp[i][], 1ll*comb[cur][pre]*dp[pre][]%p*dp[suf][]%p);
}
}
printf("%d\n", (dp[n][]+dp[n][])%p);
return ;
} /*
*/