Mashmokh’s boss, Bimokh, didn’t like Mashmokh. So he fired him. Mashmokh decided to go to university and participate in ACM instead of finding a new job. He wants to become a member of Bamokh’s team. In order to join he was given some programming tasks and one week to solve them. Mashmokh is not a very experienced programmer. Actually he is not a programmer at all. So he wasn’t able to solve them. That’s why he asked you to help him with these tasks. One of these tasks is the following.
A sequence of l integers b1, b2, …, bl (1 ≤ b1 ≤ b2 ≤ … ≤ bl ≤ n) is called good if each number divides (without a remainder) by the next number in the sequence. More formally for all i (1 ≤ i ≤ l - 1).
Given n and k find the number of good sequences of length k. As the answer can be rather large print it modulo 1000000007 (109 + 7).
Input
The first line of input contains two space-separated integers n, k (1 ≤ n, k ≤ 2000).
Output
Output a single integer — the number of good sequences of length k modulo 1000000007 (109 + 7).
Input
3 2
Output
5
Input
6 4
Output
39
Input
2 1
Output
2
Note
In the first sample the good sequences are: [1, 1], [2, 2], [3, 3], [1, 2], [1, 3].
题意:n表示序列长,在其中找长度为K的一个数能被上一个数整除的好序列个数。
考虑:以该位置元素为结尾,该位置的状态是指前一个位置元素结尾的长度为k的好序列数加上该位置与之前元素组成的长度为k的好序列数。
有三个要注意的点并且要将它们联系在一起。
长度k。整除。结尾。
回答:遍历序列,以每个元素为结尾,找其倍数,加到下一长度元素为该元素倍数的状态值上(状态值为以该元素为结尾好序列的个数)。这样的话也可以将视角转化到该长度,则该长度是由上一长度该元素的因子状态值累加而成。
长度k为i大循环,遍历长度为n的序列,当遍历到元素j时,用另一个循环p来找到j的倍数,即能整除j的元素,将以j为结尾的长度i-1的状态值加到以j的倍数为结尾的长度为i+1的状态上。即以j为定位将其上一长度的值加到所有j的倍数这一长度的状态值上,这样长度为0到k所有的都被上一长度以每个序列元素为结尾,找到它的个数将其状态值添加到该长度元素倍数上,像n=5,k=4,以j=2元素为结尾,它的倍数有2,4,将dp[i][2]分别加到dp[i+1][2],dp[i+1][4]上,当然该序列够长,2或4还会是其他元素的倍数,像j=4,
那么其状态值dp[i][4]还会添加到dp[i+1][4]上。概括一下就是该长度的与上一长度的有关,并且上一长度数组所有该元素的因子,会影响到该元素。
以上是我的解题思考,还可参考以下博主的清晰解析。
https://blog.csdn.net/qq_51392086/article/details/115774113?utm_source=app&app_version=4.5.8
https://blog.csdn.net/weixin_51443397/article/details/115798041?utm_source=app&app_version=4.5.8
#include <iostream>
using namespace std;
const int mod=1e9+7;
int dp[2005][2005];
int main()
{
int n,k;
cin>>n>>k;
dp[0][1]=1;
for (int i=0;i<=k;i++)
{
for (int j=1;j<=n;j++)
{
for (int t=j; t<=n; t+=j) //找j的倍数
{
dp[i+1][t]=(dp[i+1][t]+dp[i][j])%mod;
}
}
}
int sum=0;
for (int i = 1; i <= n; i++) //将所有情况相加
{
sum=(sum+dp[k][i])%mod;
}
cout <<sum<< endl;
return 0;
}