dp - 递推
You are given an integer array a1,a2,…,an
.
The array b
is called to be a subsequence of a if it is possible to remove some elements from a to get b
.
Array b1,b2,…,bk
is called to be good if it is not empty and for every i (1≤i≤k) bi is divisible by i
.
Find the number of good subsequences in a
modulo 109+7
.
Two subsequences are considered different if index sets of numbers included in them are different. That is, the values of the elements do not matter in the comparison of subsequences. In particular, the array a
has exactly 2n−1
different subsequences (excluding an empty subsequence).
The first line contains an integer n
(1≤n≤100000) — the length of the array a
.
The next line contains integers a1,a2,…,an
(1≤ai≤106
).
Print exactly one integer — the number of good subsequences taken modulo 109+7
.
2
1 2
3
5
2 2 1 22 14
13
In the first example, all three non-empty possible subsequences are good: {1}
, {1,2}, {2}
In the second example, the possible good subsequences are: {2}
, {2,2}, {2,22}, {2,14}, {2}, {2,22}, {2,14}, {1}, {1,22}, {1,14}, {22}, {22,14}, {14}
题意 : 给你 n 个数字,对于任意位置的数你都可以选择或者不选择,构成一个新的序列,当构成新的序列满足第一个数是1的倍数,第二个数是2的倍数..以此类推询问你方案数有多少
思路分析 :
比赛的时候写了一个 dp,顺势推过去的,用 01 数组去优化的一个,dp[i][j] 表示到达第 i 个位置,且当前构成的序列可以整除 j 的方案数,但由于 n 很大,想的是用 01 滚动数组优化个,
结果凉掉了,就是有些状态是不会被转移过去,从而造成了丢失
其实一维 dp 就够, dp[i] 表示当前数作为整除 i 的数的个数,倒着推就可以了
代码示例 :
#define ll long long const ll maxn = 1e6+5; const ll maxm = 1e5+5; const ll mod = 1e9+7; const double eps = 1e-9; const double pi = acos(-1.0); const ll inf = 0x3f3f3f3f; ll n; ll a[maxm]; vector<ll>ve[maxn]; void init(){ for(ll i = 1; i <= 1e6; i++){ for(ll j = i; j <= 1e6; j += i){ ve[j].push_back(i); } } } ll dp[maxn]; void solve(){ //ll pt = 1; //dp[0][0] = 1, dp[1][0] = 1; dp[0] = 1; ll ans = 0; for(ll i = 1; i <= n; i++){ for(ll j = ve[a[i]].size()-1; j >= 0; j--){ ll x = ve[a[i]][j]; dp[x] = dp[x]+dp[x-1]; dp[x] %= mod; } } for(ll i = 1; i <= n; i++) { ans += dp[i]; ans %= mod; // printf("++++ i = %lld %lld\n", i, dp[pt][i]); } cout << ans << endl; } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); //init(); cin >> n ; for(ll i = 1; i <= n; i++) scanf("%lld", &a[i]); init(); solve(); return 0; }