小 Hi 有一个数字 k,小 Hi 可以对他进行多次变换:每次变换选择 k 的一个大于 1 的约数 d,然后将 k 变成 k/d
现在小 Hi 想将一个数字变成 1,求操作的方案数。由于方案数可能过大,你只需要输出方案数对 109+7 取模后的值。
例如对于k=10,有三种方案:10->5->1,10->1,10->2->1。
Input
一个正整数 k
1 ≤ k ≤ 106
Output
输出将 k 变成 1 的操作序列的方案数
Sample Input
10
Sample Output
3
#include<bits/stdc++.h>
using namespace std;
int dp[1000010];
const int num=1e9+7;
int main(){
int n;
cin>>n;
dp[1]=1;
for(int i=1;i<=1000000;i++){
for(int j=i+i;j<=1000000;j+=i){
dp[j]=(dp[i]+dp[j])%num;
}
}
cout<<dp[n]<<endl;
return 0;
}
这道题嘛我一开始想的是每一个最后都到1,每一个约数都到1,所以每一层约数的个数累加,再注意细节之类的,但是计算约数的个数虽然有公式,比价复杂,估计会超时。
再是由一个数递减到其约数,约数可以再递减,很明显的动态规划,由于本人不是很熟,所以hh了。只会照搬。
一个数可以到1,除本身以外的其他约数,自底向上的话,关系又是倍数的话,那么两个循环条件是很显然的,当然不是对我自己,累加约数的情况。注意取余。由此看来一般动态规划的题还是很好解的,在一定的训练下。