https://www.luogu.org/blog/user55639/solution-p2467
思维难度挺大。。正解不容易想
由于原来数组两维可能比较浪费,我们注意到每次更新dp数组只需要前一位的状态,所以我们可以利用滚动数组优化。这里令偶数位存在0中,奇数位存在1中,两者之间的变化通过&1来实现,这样能节省很多时间。最后注意该方程只是考虑了开头为峰的情况,结果还应当×2才是所有的结果。
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
int f[2][5010];
int n,mod;
int main()
{
scanf("%d%d",&n,&mod);
f[0][2]=1;
for(int i=3;i<=n;i++)
for(int j=2;j<=i;j++)
f[i&1][j]=(f[i&1][j-1]+f[(i-1)&1][i-j+1])%mod;
int ans=0;
for(int i=2;i<=n;i++)
{
ans=(ans+f[n&1][i])%mod;
}
printf("%d",(ans<<1)%mod);
return 0;
}