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).
The first line of input contains two space-separated integers n, k (1 ≤ n, k ≤ 2000).
Output a single integer — the number of good sequences of length k modulo 1000000007 (109 + 7).
3 2
5
6 4
39
2 1
2
In the first sample the good sequences are: [1, 1], [2, 2], [3, 3], [1, 2], [1, 3].
链接http://codeforces.com/problemset/problem/414/B
一道简单的dp题,一开始想复杂了,搞了好久,后来才发现其实很简单的,对枚举比较熟悉的话一下子就能想出来的
主要的状态转移过程:当前位置的数到下一位置只有可能是当前数的任意倍数且不大于n
状态转移方程:(i是当前位置,j是当前位置的数字,l是不大于n的j的倍数)dp[i+1][l]=dp[i+1][l]+dp[i][j]
ac代码
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int M=1000000007;
int n,k;
long long dp[2222][2222];
int main()
{
long long ans=0;
int i,j,l;
memset(dp,0,sizeof(dp));
scanf("%d%d",&n,&k);
for(i=1;i<=n;++i)
{
dp[0][i]=1; //不要忘记初始化赋值
}
for(i=0;i<k;++i)
{
for(j=1;j<=n;++j)
{
for(l=j;l<=n;l+=j)<span style="white-space:pre"> </span>//三重枚举
{
dp[i+1][l]+=dp[i][j]; //是累加不是等于,同一个值有多个约数
dp[i+1][l]%=M;<span style="white-space:pre"> </span>//不要忘记mod,在这里wa了一次
}
}
}
for(i=1;i<=n;++i)
{
ans+=dp[k-1][i];
ans%=M;
}
printf("%I64d\n",ans);
return 0;
}