定义
d
p
[
i
]
[
j
]
dp[i][j]
dp[i][j] 表示长度为
i
+
1
i+1
i+1 且最后一个数字为
j
j
j 的合法数列个数
对于每个位置,我们需要:
统计前一个位置所有数字的方案总和
减去不满足条件的方案数(即对于当前数
j
j
j,减去所有是
j
j
j 倍数位置的方案数)
最终答案是最后一行所有位置的方案数之和
由于答案可能很大,需要对
1000000007
1000000007
1000000007 取模
代码
#include<iostream>#include<vector>usingnamespace std;intmain(){int n, k;
cin >> n >> k;constint mod =1000000007;// dp[i][j]表示长度为i+1且最后一个数字为j的合法数列个数
vector<vector<int>>dp(n,vector<int>(k+5,0));// 初始化长度为1的情况for(int i =1; i <= k;++i)
dp[0][i]=1;// 动态规划过程for(int i =1; i < n;++i){// 计算前一行的和int sum =0;for(int j =1; j <= k;++j){
sum =(sum + dp[i-1][j])% mod;}// 对每个数字计算当前位置的方案数for(int j =1; j <= k;++j){
dp[i][j]= sum;// 减去不满足条件的情况for(int mul = j*2; mul <= k; mul += j){
dp[i][j]=(dp[i][j]- dp[i-1][mul]+ mod)% mod;}}}// 计算最终答案int ans =0;for(int i =1; i <= k;++i){
ans =(ans + dp[n-1][i])% mod;}
cout << ans << endl;return0;}
importjava.util.*;publicclassMain{publicstaticvoidmain(String[] args){Scanner sc =newScanner(System.in);int n = sc.nextInt();int k = sc.nextInt();finalint mod =1000000007;int[][] dp =newint[n][k+5];// 初始化for(int i =1; i <= k;++i)
dp[0][i]=1;// 动态规划for(int i =1; i < n;++i){int sum =0;for(int j =1; j <= k;++j){
sum =(sum + dp[i-1][j])% mod;}for(int j =1; j <= k;++j){
dp[i][j]= sum;for(int mul = j*2; mul <= k; mul += j){
dp[i][j]=((dp[i][j]- dp[i-1][mul])% mod + mod)% mod;}}}// 计算结果int ans =0;for(int i =1; i <= k;++i){
ans =(ans + dp[n-1][i])% mod;}System.out.println(ans);}}
defsolve(n, k):
mod =1000000007
dp =[[0]*(k+5)for _ inrange(n)]# 初始化for i inrange(1, k+1):
dp[0][i]=1# 动态规划for i inrange(1, n):# 计算前一行的和
sum_prev =sum(dp[i-1][j]for j inrange(1, k+1))% mod
# 计算当前行for j inrange(1, k+1):
dp[i][j]= sum_prev
# 减去不满足条件的情况
mul = j *2while mul <= k:
dp[i][j]=(dp[i][j]- dp[i-1][mul])% mod
mul += j
# 计算最终答案
ans =sum(dp[n-1][i]for i inrange(1, k+1))% mod
return ans
n, k =map(int,input().split())print(solve(n, k))
算法及复杂度
算法:动态规划
时间复杂度:
O
(
n
⋅
k
⋅
log
k
)
\mathcal{O}(n \cdot k \cdot \log k)
O(n⋅k⋅logk) - 对于每个位置需要处理
k
k
k 个数,每个数需要检查其倍数
空间复杂度:
O
(
n
⋅
k
)
\mathcal{O}(n \cdot k)
O(n⋅k) - 需要二维dp数组存储状态