luogu P4451 [国家集训队]整数的lqp拆分
题面传送门
对于这道题,用递推的思想。
设\(f_i\)表示\(i\)这个数的\(lqp\)拆分的值,那么考虑一下,除了自身的拆分,其他拆分一定是\(x\times(i-x)\),其中\(x\)是一个多数组成的集合,而\((i-x)\)是一个单个的数,然后问题就变成了怎么求\(x\)这个集合的\(lqp\)拆分的答案。因为这是递推,状态记录过,所以可直接的出结果。
代码实现:
#include<cstdio>
using namespace std;
long long f[1000039]={0,1,1},n,ans,q[1000039]={0,1,2};
int main(){
register int i,j;
scanf("%lld",&n);
for(i=3;i<=n;i++) f[i]=f[i-1]+f[i-2];
for(i=3;i<=n;i++){
for(j=1;j<i;j++) q[i]=(q[j]*f[i-j]+q[i])%1000000007;
q[i]=(q[i]+f[i])%1000000007;
}
printf("%d",q[n]);
}
但这只能过 \(5000\) 的数据,怎么办呢?
我们注意到\(q_i=\sum\limits_{j=1}^{i}{q_j'\times f_{i-j+1}}\) ,而\(q_{i-1}=\sum\limits_{j=1}^{i-1}{q_j\times f_{i-j}}\)因为 \(q_i\)的求和 中一定带有\(q_{i-1}\times f_1\) ,所以先加上去,然后观察\(q_{i-2}=\sum\limits_{j=1}^{i-2}{q_j\times f_{i-j-1}}\) 而\(f_{i-j-1}+f_{i-j}=f_{i-j+1}\),所以直接可得 \(q_i=q_{i-1}\times 2+q_{i-2}\)
代码实现:
#include<cstdio>
using namespace std;
long long f[1000039]={0,1,1},n,ans,q[1000039]={0,1,2};
int main(){
register int i,j;
scanf("%lld",&n);
for(i=3;i<=n;i++)q[i]=(q[i-1]*2+q[i-2])%1000000007;
printf("%lld",q[n]);
}