【题解】序列

题目描述

  一个长度为k的整数序列b1,b2,...,bk(1≤b1≤b2≤...≤bk≤N)称为“好序列”当且仅当后一个数是前一个数的倍数,即bi+1是bi的倍数对任意的i(1≤i≤k-1)成立。

  给定N和k,请算出有多少个长度为k的“好序列”,答案对1000000007取模。

 

输入格式

  一行,包含2个用空格隔开的整数N和k。

 

输出格式

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

 

输入样例

3 2

 

输出样例

5

 

数据规模

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

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

 

题解

  我们枚举因子来传递状态给倍数即可,这里可以用滚动数组优化。

#include <iostream>
#include <fstream>

#define MAX_N 2001
#define MAX_M 2001

#define MOD 1000000007

using namespace std;

int n, m;
int dp[MAX_N];
int ans;

int main()
{
    cin >> n >> m;
    for(register int i = n; i; --i)
    {
        dp[i] = 1;
    }
    for(register int i = 2; i <= m; ++i)
    {
        for(register int j = n >> 1; j; --j)
        {
            for(register int k = j << 1; k <= n; k += j)
            {
                dp[k] += dp[j];
                if(dp[k] >= MOD) dp[k] -= MOD;
            }
        }
    }
    for(register int i = n; i; --i)
    {
        ans += dp[i];
        if(ans >= MOD) ans -= MOD;
    }
    cout << ans;
    return 0;
}
参考程序

 

转载于:https://www.cnblogs.com/kcn999/p/10805301.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值