NH序列(dp)

题目描述
一个长度为k的整数序列b1,b2,…,bk(1≤b1≤b2≤…≤bk≤N)称为“好序列”当且仅当后一个数是前一个数的倍数,即bi+1是bi的倍数对任意的i(1≤i≤k-1)成立。
给定N和k,请算出有多少个长度为k的“好序列”,答案对1000000007取模。

输入
输入共1行,包含2个用空格隔开的整数N和k。

输出
输出共1行,包含一个整数,表示长度为k的“好序列”的个数对1000000007取模后的结果。

样例输入
3 2

样例输出
5

提示
“好序列”为:[1,1],[1,2],[1,3],[2,2],[3,3]。

对于40%的数据,1≤N≤30,1≤k≤10。
对于100%的数据,1≤N≤2000,1≤k≤2000。

思路
将第i位为j的方法总数视为dp[i][j],可推出dp递推公式dp[i][j*k]=dp[i][j*k]+dp[i-1][j]

代码实现

#pragma GCC optimize(3,"Ofast","inline")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=2005;
const int M=10005;
const int INF=0x3f3f3f;
const ull sed=31;
const ll mod=1e9+7;
const double eps=1e-9;
typedef pair<int,int>P;
typedef pair<double,double>Pd;
 
int n,m;
ll dp[N][N],ans;
 
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) dp[1][i]=1;
    for(int i=2;i<=m;i++)
    {
        for(int j=n;j;j--)
        {
            for(int k=1;k<=n/j;k++)
            {
                dp[i][j*k]=(dp[i][j*k]+dp[i-1][j])%mod;
            }
        }
    }
    for(int i=1;i<=n;i++) ans=(ans+dp[m][i])%mod;
    printf("%lld\n",ans);
    return 0;
}
发布了235 篇原创文章 · 获赞 13 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_43935894/article/details/104171940