Date:2022.03.17
题目描述
HXY突发奇想,她想要找到一个正整数序列,满足序列中所有的数不超过n,序列长度为p,且除了第一个数外,所有的数都能被前一个数整除(即是前一个数的倍数)。很快她找到了一个这样的序列。可是她觉得还不够,想要知道这样的序列有多少个,可她被惊人的数据范围吓怕了。现在她找到了你,请你来帮助她解决这个问题。(因为结果可能会很大,请输出对1e9+7取模后的值)
输入格式
第一行,两个正整数n,p。
输出格式
仅一行,一个正整数,表示满足条件序列的个数对1e9+7取模后的值。
输入输出样例
输入 #1复制
3 2
输出 #1复制
5
输入 #2复制
6 4
输出 #2复制
39
说明/提示
数据范围:
对于10%的数据,p=1;
对于30%的数据,1<=n,p<=10;
对于60%的数据,1<=n,p<=500;
对于100%的数据,1<=n,p<=2000。
思路:
f
[
i
]
[
j
]
:
f[i][j]:
f[i][j]:以第
i
i
i个字符结尾,长度为
j
j
j串的合法方案数。
状态转移方程:
f
[
i
]
[
j
]
+
=
f
[
k
]
[
j
−
1
]
;
【
其
中
i
%
k
=
=
0
】
f[i][j]+=f[k][j-1];【其中i\%k==0】
f[i][j]+=f[k][j−1];【其中i%k==0】
初始状态:
f
[
i
]
[
1
]
=
1
;
f[i][1]=1;
f[i][1]=1;【即只有它自己一个数】
由于三维,打表出所有
k
k
k,即使2000的约数也只有20个,所以k很小不必担心。
答案可以是以每个元素结尾的,累加下。
代码如下:
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long LL;
const LL N = 2020,INF=0x3f3f3f3f3f3f3f3f,mod=1e9+7;
typedef pair<LL, LL> PII;
LL t,n,m,k,f[N][N],sum[N];
vector<LL>v[N];
int main()
{
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=0;i<=n;i++) f[i][1]=1;
for(int i=1;i<N;i++)
{
for(int j=1;j<=i;j++)
if(i%j==0) v[i].push_back(j);
}
for(int i=1;i<=n;i++)
for(int j=2;j<=m;j++)
for(int k=0;k<v[i].size();k++)
f[i][j]=(f[i][j]+f[v[i][k]][j-1])%mod;
LL sum=0;
for(int i=1;i<=n;i++) sum=(sum+f[i][m])%mod;
cout<<sum;
return 0;
}