首页 > 试题广场 >

小易喜欢的数列

[编程题]小易喜欢的数列
  • 热度指数:132 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
小易非常喜欢拥有以下性质的数列:
1、数列的长度为n
2、数列中的每个数都在1到k之间(包括1和k)
3、对于位置相邻的两个数A和B(A在B前),都满足(A <= B)或(A mod B != 0)(满足其一即可)
例如,当n = 4, k = 7
那么{1,7,7,2},它的长度是4,所有数字也在1到7范围内,并且满足第三条性质,所以小易是喜欢这个数列的
但是小易不喜欢{4,4,4,2}这个数列。小易给出n和k,希望你能帮他求出有多少个是他会喜欢的数列。

输入描述:
输入包括两个整数n和k(1 ≤ n ≤ 10, 1 ≤ k ≤ 10^5)


输出描述:
输出一个整数,即满足要求的数列个数,因为答案可能很大,输出对1,000,000,007取模的结果。
示例1

输入

2 2

输出

3
#include<iostream>
#include<vector>
using namespace std;
int main() {
	int n, k;
	cin >> n >> k;
	vector<vector<int>>arr(n + 1, vector<int>(k + 1, 0));
	const int t = 1000000007;
	//数列第一位取各种值的情况都为1
	for (int i = 1; i <= k; i++)
		arr[1][i] = 1;
	//根据计算到的数列前一位在各种取值情况下的可能数,获得后一位的各种取值可能数
	//前一位的值应小于等于后一位,或大于但不是整数倍
	for (int i = 2; i <= n; i++) {
                //上一位的所有情况取值可能总和数目
		int left_total = 0;
		for (int j = 1; j <= k; j++) {
			left_total = (left_total + arr[i - 1][j]) % t;
		}
		//下一行的数列放不同值时的取值可能计数
		for (int j = 1; j <= k; j++) {
			arr[i][j] = left_total;
                        //减去整数倍的
			for (int p = 2 * j; p <= k; p += j)
				arr[i][j] = (arr[i][j] - arr[i - 1][p]) % t;
		}
	}
	int count = 0;
	for (int i = 1; i <= k; i++)
		count = (count + arr[n][i]) % t;
	cout << count;

	system("pause");
	return 0;
}

发表于 2019-09-20 14:49:26 回复(0)