题目描述
 已知一个长度为l的序列:b1,b2,b3,…,bl (1<=b1<=b2<=b3<=…<=bl<=n)。若这个序列满足每个元素是它后续元素的因子,换句话说就是对于任意的i (2<=i<=l)都满足bi%bi-1=0 (其中“%”代表求余),则称这个序列是完美的。你的任务是对于给定的n和l,计算出一共有多少序列是完美序列。由于答案很大,所有输出答案对1000000007取余后的结果。
输入
 输入的第一行为一个正整数T (T<=1000),代表一共有T组测试数据。
每组测试数据包含两个正整数n,l (1<=n, l<=2000),分别代表序列中元素大小的最大值和序列的长度。
输出
 对于每组测试数据,输出一行包含一个整数,代表答案对1000000007取余后的结果。
样例输入
 3
 3 2
 6 4
 2 1
 样例输出
 5
 39
 2
ps:
这个题目真的看了好久好久…
原来这是一个二维dp,但是题解都看得很费劲。
- 首先明确dp[i][j]表示长度为i,最后一个数为j的序列的种数
 - bi%bi-1=0 (i-1)是下标,这句话的意思是,对于任意的i,前一个数是后一个数的因子
 - 状态转移方程
dp[i+1][p]=dp[i+1][p]+dp[i][x];//p是x的倍数 
打表
 我们拿3 2举个例子,长度为2且最大值为3代表最大值可以为1 2 3,那么就有
 下面都是符合3 2这组数据的
-  
1 1
 -  
1 2
 -  
2 2
 -  
1 3
 -  
3 3
都是长度为2 ,且最大值为3,且前一个数是后一个数的因子,我们把它们结合起来就是 -  
长度为2最大值为1,—— 2 1(1 1)
 -  
长度为2最大值为2,—— 2 2(1 2,2 2)
 -  
长度为2最大值为3,—— 2 3(1 3,3 3)
把它们加起来就是答案了
1+2+2=5 
- 以6 4为例,值为a[6][4]+a[5][4]+a[4][4]+a[3][4]+a[2][4]+a[1][4]=16+4+10+4+4+1=39
 - a[6][4]=a[5][4]+a[5][2]+a[5][1]
 - 即a[i][j]为a[i-1][w]的和,w为j的因子
 
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 2e3 + 5;
ll dp[maxn][maxn];
int main()
{
   
    int n, l, t;
    for (int i = 1; i < maxn; ++i)
        dp[1][i] = 1; //长度为1的都是只有一种
    for (int i = 1; i < maxn - 1; ++i)
    {
    //因为下面的代码是从i+1开始的,为了防止溢出,这里就要减去1
        for (int x = 1; x <= maxn; ++x)
        {
   
            for (int p = x; p < maxn; p += x) //p是x的倍数
                dp[i + 1][p] = (dp[i + 1][p] + dp[i][x]) % 1000000007;
        }
    }
    scanf("%d", &t);
    while (t--)
    {
   
        scanf("%d %d", &n, &l);
        int ans = 0;
        for (int i = 1; i <= n; ++i)
            ans = (ans + dp[l][i]) % 1000000007;
        printf("%d\n", ans);
    }
    return 0;
}
  | 没有在长夜痛哭过的人,不足以谈人生——歌德 | 
|---|

京公网安备 11010502036488号