小易喜歡的數列(網易18校招內推)
阿新 • • 發佈:2019-02-19
小易非常喜歡擁有以下性質的數列:
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,希望你能幫他求出有多少個是他會喜歡的數列。
示例1
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
這裡使用動態規劃。a[i][j]表示長度為i以j結尾的數列,滿足dp條件:根據長度為i-1的數列數能得到的長度為i的數列數,長度為i尾數為j的數列數 = 長度為i-1的數列數 - 長度為i-1尾數是j的倍數的。初始置i=1的a[1][j]為1,最後輸出a[n][j]。#include <iostream> using namespace std; int main() { int n, k; int res = 0; int m = 1000000007; cin >> n >> k; //i表示數列長度、j表示數列以j結尾 int a[11][100001]; for(int i = 1; i <= k; i++) a[1][i] = 1; int sum, sum1; for(int i = 2; i <= n; i++) { sum = 0; //長度為i-1的數列數目 for(int j = 1; j <= k; j++) { sum += a[i-1][j]; sum %= m; } for(int j = 1; j <= k; j++) { sum1 = 0; for(int x = j+j; x <= k; x+=j) { sum1 += a[i-1][x]; sum1 %= m; } //長度為i尾數為j的數列數目 = 長度為i-1的所有 減去 長度為i-1尾數是j的倍數的 a[i][j] = (sum - sum1) % m; } } //int res; for(int j = 1; j <= k; j++) { res += a[n][j]; res %= m; } cout << res; return 0; }