小易非常喜欢拥有以下性质的数列:
1、数列的长度为n
2、数列中的每个数都在1到k之间(包括1和k)
3、对于位置相邻的两个数A和B(A在B前),都满足(A <= B)或(A mod B != 0)(满足其一即可)
例如,当n = 4, k = 7
那么{1,7,7,2},它的长度是4,所有数字也在1到7范围内,并且满足第三条性质,所以小易是喜欢这个数列的
但是小易不喜欢{4,4,4,2}这个数列。小易给出n和k,希望你能帮他求出有多少个是他会喜欢的数列。
输入包括两个整数n和k(1 ≤ n ≤ 10, 1 ≤ k ≤ 10^5)
输出一个整数,即满足要求的数列个数,因为答案可能很大,输出对1,000,000,007取模的结果。
2 2
3
//AC代码: #include<stdio.h> #include<string.h> int dp[15][100005]; const int mod=1000000007; int main(){ int n,k,i,j,q; //freopen("input.txt","r",stdin); while(scanf("%d%d",&n,&k)!=EOF){ memset(dp,0,sizeof(dp)); for(i=1;i<=k;i++) dp[1][i]=1; for(i=2;i<=n;i++){ int sum=0; for(j=1;j<=k;j++) sum=(sum+dp[i-1][j])%mod; for(j=1;j<=k;j++){ dp[i][j]=sum; for(q=j*2;q<=k;q+=j) dp[i][j]=(dp[i][j]-dp[i-1][q]+mod)%mod; } } int res=0; for(i=1;i<=k;i++) res=(res+dp[n][i])%mod; printf("%d\n",res); } }//用dp[i][j]表示长度为i且必须以j结尾的方法
//童山公爵的代码 //C++版,附上了自己的注释,可能会容易懂一点 #include<iostream> using namespace std; int dp[11][100005]; //dp[i][j]表示长度为i,尾数为j的合法数列共有多少个 int main(){ int n,k,i,j,mod=1000000007; //mod是题目给出的,防止数字过大 cin>>n>>k; for(i=1;i<=k;i++) dp[1][i]=1; //初始化。长度为1,尾数为i的数列只有一个 for(i=2;i<=n;i++){ int sum=0; for(j=1;j<=k;j++) sum=(sum+dp[i-1][j])%mod; //dp[i][m]=(所有的dp[i-1][j]相加,再在第i位加上尾数m)- 不合法的数列个数=sum - illegal for(j=1;j<=k;j++){ int p=2; //这个表示倍数,凡是前一位数字是p*j的都是非法数列,因为 p*j>j && p*j%j==0,违反了第三个条件 int illegal=0; while(p*j<=k){ illegal=(illegal+dp[i-1][p*j]%mod)%mod; p++; } dp[i][j]=(sum-illegal+mod)%mod; //原本sum>illegal,但是因为illegal和sum都是求的取模,所以这里sum可能<illegal } } int sum=0; for(int i=1;i<=k;i++) sum=(sum+dp[n][i])%mod; cout<<sum; }
/* 如果我们确定这个数列的第一个数是i,那么第二个数可以是1到k中除了是i的约数的任何数。 于是我们定义dp[j][i]表示长度为i最后一个数是j的小易喜欢的数列的数量,然后挨着转移即可 实现请参考参考代码。 */ #include <bits/stdc++.h> using namespace std; const int mod = 1e9 + 7; const int maxn = 1e5 + 5; int dp[maxn][15]; int n, k; int main() { cin >> n >> k; dp[1][0] = 1; for(int i = 1; i <= n; i++) { int sum = 0; for(int j = 1; j <= k; j++) { sum += dp[j][i - 1]; sum %= mod; } for(int j = 1; j <= k; j++) { int sum2 = 0; for(int z = j + j; z <= k; z += j) { sum2 += dp[z][i - 1]; sum2 %= mod; } dp[j][i] = (sum - sum2 + mod) % mod; } } int ans = 0; for(int j = 1; j <= k; j++) { ans += dp[j][n]; ans %= mod; } cout << ans << endl; return 0; }
#include <iostream> #include <vector> #include <queue> #include <functional> #include <algorithm> using namespace std; class Solution { private: int n; int k; long res; int mod = 1000000007; private: void init() { cin >> n >> k; res = 0; } void write_result() { cout << res; } void calculate_result() { if (n == 0 || k == 0) return; //res = func1(n + 1, 1); res = func2(); } int func1(int index, int pre_num) { int count = 0; if (index < 2) count = 1; else { for (int i = 1; i < pre_num; i++) if (pre_num%i != 0) count += func1(index - 1, i); for (int i = pre_num; i <= k; i++) count += func1(index - 1, i); } return count; } long func2() { vector<long> vt(k + 1, 1); long vtsum = k; vector<vector<int>> noncdt(k + 1); for (int i = 1; i <= k; i++) { for (int j = i + i; j <= k; j += i) { noncdt[i].push_back(j); } } for (int col = 1; col < n; col++) { long newsum = 0; for (int row = 1; row <= k; row++) { long del = 0; for (auto d : noncdt[row]) { del += vt[d]; del %= mod; } vt[row] = (vtsum - del + mod) % mod; newsum += vt[row]; newsum %= mod; } vtsum = newsum; } return vtsum; } public: void solve() { init(); calculate_result(); write_result(); } }; int main() { Solution s; s.solve(); return 0; }
import java.util.*;
public class Sim {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int k = in.nextInt();
int[][] dp = new int[k+5][n+5];
dp[1][0] = 1;
for(int i = 1; i <= n; i++) {
int sum = 0;
for(int j = 1; j <= k; j++) {
sum += dp[j][i - 1];
sum %= 1000000007;
}
for(int j = 1; j <= k; j++) {
int sum2 = 0;
for(int z = j + j; z <= k; z += j) {
sum2 += dp[z][i - 1];
sum2 %= 1000000007;
}
dp[j][i] = (sum - sum2 + 1000000007) % 1000000007;
}
}
int result = 0;
for(int i = 0; i <= k; i++) {
result += dp[i][n];
result %= 1000000007;
}
System.out.println(result);
}
}
#include <bits/stdc++.h> using namespace std; const int M = 1e9+7; int main(){ int n, k, s=0; scanf("%d%d", &n, &k); int dp[15][100003]; memset(dp, 0, sizeof(dp)); for(int i=1;i<=k;i++) dp[1][i] = 1; for(int i=2;i<=n;i++){ int t=0; for(int j=1;j<=k;j++) t = (t+dp[i-1][j])%M; for(int j=1;j<=k;j++){ dp[i][j] = t; for(int h=2*j;h<=k;h+=j) dp[i][j] = (dp[i][j]-dp[i-1][h]+M)%M; } } for(int i=1;i<=k;i++) s = (s+dp[n][i])%M; printf("%d\n", s); return 0; }
#include <stdio.h> #include <vector> #include <algorithm> #include <string.h> #include <limits.h> #include <string> #include <iostream> #include <queue> #include <math.h> #include <map> #include <stack> #include <set> #include <list> #include <forward_list> #define left (now<<1) #define right ((now<<1)+1) #define mid ((l + r) >> 1) #define midmid ((r + mid) >> 1) #define LONG_LONG_MIN -9223372036854775808ll #define LONG_LONG_MAX 9223372036854775807ll using namespace std; typedef long long int ll; const int MAXN = 1e5 + 10; const int MOD = 1e9 + 7; ll dp[12][MAXN],sum[12]; ll n,k; vector<int> p[MAXN]; bool can[MAXN]; int main(){ scanf("%lld%lld",&n,&k); memset(can,true,sizeof(can)); for(int i = 2; i <= k; ++i){ p[i].push_back(1); for(int j = i + i; j <= k; j += i){ p[j].push_back(i); can[j] = false; } // printf("%d: ",i); // for(int j = 0; j < p[i].size(); ++j){ // printf("%d ",p[i][j]); // } // printf("\n"); } memset(dp,0,sizeof(dp)); memset(sum,0,sizeof(sum)); for(ll i = 1; i <= k; ++i){ dp[n][i] = 1; sum[n] += 1; } for(ll i = n - 1; i >= 1; --i){ for(ll j = 1; j <= k; ++j){ dp[i][j] = sum[i + 1]; for(ll s = 0; s < p[j].size(); ++s){ dp[i][j] = dp[i][j] - dp[i + 1][p[j][s]]; if(dp[i][j] < 0){ dp[i][j] += MOD;} } sum[i] = sum[i] + dp[i][j]; sum[i] %= MOD; } } printf("%lld\n",sum[1]); return 0; }
python elegant solution
pass 80%
n, k = list(map(int, input().strip().split())) # dp[i][j] += dp[i-1][m] for m in k dp = [[0] * (k + 1) for _ in range(n)] for j in range(1, k + 1): dp[0][j] = 1 for i in range(1, n): total = sum(dp[i - 1]) for j in range(1, k + 1): dp[i][j] = total for m in range(2 * j, k + 1, j): dp[i][j] -= dp[i - 1][m] print(sum(dp[n - 1]) % 1000000007)
#include <iostream> using namespace std; int main(void) { int mod = 1000000007; int dp[11][100005] = { 0 };//dp[i][j] ,i为数列长度(n),j为数列末尾的数字(k) // memset(dp, 0, sizeof(dp)); int n, k; cin >> n >> k; for (int j = 1; j <= k; j++) dp[1][j] = 1; for (int i = 2; 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++) { int mul = 2; int illegal = 0; while (mul*j <= k) { illegal = (illegal + dp[i - 1][mul*j]) % mod; mul++; } dp[i][j] = (sum - illegal + mod) % mod; } } int res = 0; for (int i = n, j = 1; j <= k; j++) res = (res + dp[i][j]) % mod; cout << res << endl; return 0; }
import java.util.Scanner; public class Problem_201703 { private static final int MOD = 1000000007; public static void main(String[] args) { Scanner scan = new Scanner(System.in); while (scan.hasNext()) { int n = scan.nextInt(); int k = scan.nextInt(); //dp[i][j]表示长度为i的序列以j结束数字的数列个数 //dp[i][j] = dp[i - 1][m] (1 <= m <= k)并且(m,j)是一个有效的序列 int[][] dp = new int[n + 1][k + 1]; dp[0][1] = 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++) { //删除所有不满足条件的情况,类似素数筛选的过程 int invalid = 0; int p = 2; while (p * j <= k) { //dp[i - 1][p * j]违反了A % B != 0,因此剔除 invalid = (invalid + dp[i - 1][p * j]) % MOD; p++; } //为初始化添加增量 dp[i][j] = (sum - invalid + MOD) % MOD; } } int res = 0; for (int i = 1; i <= k; i++) { res = (res + dp[n][i]) % MOD; } System.out.println(res); } scan.close(); } }
var readline = require('readline')const rl = readline.createInterface({input: process.stdin,output: process.stdout})rl.on('line', function (line) {var tokens = line.split(' ')console.log(dpHelper3(1, +tokens[0], +tokens[1]));})
function dpHelper3(prev, n, k) {var dp = [], sum = 0, m=1e9+7;dp[0] = 0;for (var i = 1; i <= k; i++) {dp[i] = 1;}for (var j = 1; j < n; j++) {sum = dp.reduce(function (pre, val) { return (pre + val) % m });for (var p = 1; p <= k; p++) {var noneValid = 0;for(var row = 2*p; row <=k; row+=p){noneValid += dp[row];noneValid %= m;}dp[p] = (sum - noneValid) % m;}}return dp.reduce(function (pre, val) { return (pre + val) % m });}
#include <iostream> #include <deque> #include <algorithm> using namespace std; int main() { int mod=1000000007; int n; int k; cin>>n>>k; int state[n+1][k+1]; for(int i=0;i<n+1;i++) { for(int j=0;j<k+1;j++) { state[i][j]=0; //cout<<state[i][j]<<' '; } //cout<<endl; } state[0][1]=1; for(int i=1;i<=n;i++) { int sum = 0; for(int j=1;j<=k;j++) { sum=(sum+state[i-1][j])%mod; } for(int j=1;j<=k;j++) { int invalid = 0; int p=2; while(p*j<=k) { invalid = (invalid + state[i-1][p*j])%mod; p++; } state[i][j]=(sum-invalid+mod)%mod; } } int sum = 0; for(int i=1;i<=k;i++) sum=(sum+state[n][i])%mod; cout<<sum<<endl; return 0; }
import java.util.Scanner; public class Main { static final int MOD = 1000000007; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int k = sc.nextInt(); //res[i][]j表示第i个数字为j的次数 int[][] res = new int[n + 1][k + 1]; res[0][1] = 1; for (int i = 1; i <= n; i++) { int sum = 0; for (int j = 1; j <= k; j++) sum = (sum + res[i - 1][j]) % MOD; for (int j = 1; j <= k; j++) { int p = 2; int invalid = 0; while (p * j <= k) { //计算不符合要求的数字和 invalid = (invalid + res[i - 1][p * j]) % MOD; p++; } res[i][j] = (sum - invalid + MOD) % MOD; } } int sum = 0; for (int i = 1; i <= k; i++) sum = (sum + res[n][i]) % MOD; System.out.println(sum); sc.close(); } }
import java.util.Scanner; public class Main { static final int mod = 1000000007; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int k = scanner.nextInt(); int[][] state = new int[n+1][k+1]; state[0][1] = 1; for(int i=1; i<=n; i++) { int sum = 0; for(int j=1; j<=k; j++) { sum = (sum + state[i-1][j]) % mod; } for(int j=1; j<=k; j++) { int invalid = 0; int p = 2; while(p*j <= k) { invalid = (invalid + state[i-1][p*j]) % mod; p++; } state[i][j] = (sum - invalid + mod) % mod; } } int sum = 0; for(int i=1; i<=k; i++) { sum = (sum + state[n][i]) % mod; } System.out.println(sum); scanner.close(); } }