题意:
给定n和k,
问有多少种长度为k的序列,满足任意相邻元素的积<=n
答案对1e9+7取模
数据范围:1<=n<=1e9,2<=k<=100
解法:
令
d
[
i
]
[
j
]
d[i][j]
d[i][j]表示第i个数填 j 的方案数,
转移方程:
d
[
i
]
[
j
]
=
∑
p
=
1
n
/
j
d
[
i
−
1
]
[
p
]
d[i][j]=\sum_{p=1}^{n/j}d[i-1][p]
d[i][j]=∑p=1n/jd[i−1][p]
n/j的取值最多只有2sqrt(n)种,因此第二维的空间大小可以降到2sqrt(n)
code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define PI pair<int,int>
const int maxm=1e5+5;
const int mod=1e9+7;
int d[105][70005];
pair<int,int>p[maxm];
map<int,int>mark;
int n,k;
signed main(){
cin>>n>>k;
int m=0;
for(int i=1,j;i<=n;i=j+1){
j=n/(n/i);
p[++m]={j,j-i+1};
mark[j]=m;
}
for(int i=1;i<=m;i++){
d[1][i]=(d[1][i-1]+p[i].second)%mod;
}
for(int i=2;i<=k;i++){
for(int j=1;j<=m;j++){
d[i][j]=(d[i][j-1]+p[j].second*d[i-1][mark[n/p[j].first]]%mod)%mod;
}
}
cout<<d[k][m]<<endl;
return 0;
}