输出一个整数,即满足要求的数列个数,因为答案可能很大,输出对1,000,000,007取模的结果。
解题思路:
输入n, k; dp[i][j]表示前i位以j结尾的符合相应性质的数列。dp[i][j]=dp[i][j]+dp[i-1][x], 其中1<=i<=n, 1<=j<=k, 1<=x<=k且(x<=j或者x>j&&x%j!=0)
但是这样一看这是个三重的循环,一般情况下是会超时的。我们这种实在直接算符合条件的有多少,换种思路我们在推的时候类似于素数筛法的思想吧不符合的去掉不就可以稍微降低复杂度吗?然后我就试了下,然后就AC了。
AC代码
#include
# define f(i,m,n) for(int i=m; i<=n; i++)
using namespace std;
const int mod=1000000007;
int dp[15][100010], last, now, n, k;
int main(){
cin>>n>>k;
last=0;
f(i, 1, k){
dp[1][i]=1;
last=(last+dp[1][i]%mod)%mod;
}
f(i, 2, n){
now=0;
f(j, 1, k){
int sum=0;
for(int t=2*j; t<=k; t=t+j)
sum=(sum+dp[i-1][t])%mod;
dp[i][j]=(last-sum+mod)%mod;
now=(now+dp[i][j])%mod;
}
last=now;
}
int ans=0;
f(i, 1, k) ans=(ans+dp[n][i])%mod;
cout<