【解题报告】洛谷P6189 跑步
题目链接
https://www.luogu.com.cn/problem/P6189
思路
发现相当于给一个数字 n n n ,问你有多少种方法能使得一个不递减序列的和为 n n n
这实际上是一个分拆数的模板题目
根据OIES,这个分拆数的伪代码是
1 2 3 4 5 6 7 8 9 >def A000041 (n) : if n = = 0 : return 1 S = 0 ; J = n-1 ; k = 2 while 0 <= J: T = A000041 (J) S = S+T if is_odd (k J -= k if is_odd (k) else k k += 1 return S
然后我们就把它翻译成C++就好了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <string> using namespace std;const int maxn=100005 ;int n,p;int f[maxn]; int main () { cin>>n>>p; f[0 ]=1 ; for (int i=1 ;i<=n;i++) { int j=i-1 ,k=2 ; while (j>=0 ) { if ((k/2 )%2 ==1 ) f[i]=(f[i]+f[j])%p; else f[i]=(f[i]-f[j]+p)%p; if (k&1 ) j-=k; else j-=(k/2 ); k++; } } cout<<f[n]<<'\n' ; return 0 ; }