题解
原本使用的是正常的解题思路,但是k大于10000就会超时,V同学的题解,解决了,顺便发一下我的题解代码
原本使用的是正常的解题思路,但是k大于10000就会超时,V同学的题解,解决了,顺便发一下我的题解代码
//
// Created by HuJJun on 2021/10/16.
//
#include<iostream>
#include<cstring>
using namespace std;
long long const MOD=1e9+7;
bool const test = false; //设置为true 可以答应dp过程
long long dp[15][100005]; // dp[长度][结尾数字]
int N,K;
void output(){
if(!test) return ;
for(int i = 1 ; i <= N ; i++) {
cout << i << ":";
for (int j = 1; j <= K; j++) {
cout << dp[i][j] << " ";
}
cout << endl;
}
}
void init(){
for(int i = 1 ; i <= N ; i++)
for (int j = 1; j <= K; j++)
dp[i][j]= (i==1 ? 1 : 0);
output();
}
int main() {
cin >> N >> K;
init();
long long sum = K; //设置初始 当i=1,共有K种
for (int i = 2; i <= N; i++) { //长度
long long nextSum = 0;
for (int j = 1; j <= K; j++) { // j结尾数字
//正向求解,k大于10000超时
//*
//k为前一个数
for(int k = 1 ; k < j ; k++) //k<j 满足条件一
for(int kt = k ; kt <= K ; kt+=j) //那k加上j的倍数满足条件二
dp[i][j] += dp[i-1][kt];
dp[i][j] += dp[i-1][j]; //当k==j时 满足条件一
dp[i][j] %= MOD;
/*/
//逆向求解
dp[i][j] = sum % MOD; //设置为上一条长度满足条件个数
for (int k = j * 2; k <= K; k += j) //j的倍数,不满足条件
dp[i][j] = (dp[i][j] - dp[i - 1][k] + MOD) % MOD; // 扣除上一长度的倍数个数
nextSum = (nextSum + dp[i][j]) % MOD; //统计当前长度满足条件个数和
//*/
}
sum = nextSum; //保存,下一长度需要使用
}
output();
sum = 0;
for (int i = 1; i <= K; i++) //答案求和
sum = (sum + dp[N][i]) % MOD;
cout << sum << endl;
return 0;
} 
京公网安备 11010502036488号