【解题报告】洛谷P6189 跑步

【解题报告】洛谷P6189 跑步

题目链接

https://www.luogu.com.cn/problem/P6189

思路

发现相当于给一个数字 \(n\) ,问你有多少种方法能使得一个不递减序列的和为 \(n\)

这实际上是一个分拆数的模板题目

根据OIES,这个分拆数的伪代码是

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//2) else S-T
       J -= k if is_odd(k) else k//2
       k += 1
   return S

然后我们就把它翻译成C++就好了

#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;
}
posted @ 2021-10-13 23:36  wweiyi  阅读(39)  评论(0编辑  收藏  举报
js脚本