dp - 递推

Posted ccut-ry

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了dp - 递推相关的知识,希望对你有一定的参考价值。

C. Multiplicity
time limit per test
3 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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 (1ik) 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).

Input

The first line contains an integer n

(1n100000) — the length of the array a

.

The next line contains integers a1,a2,,an

(1ai106

).

Output

Print exactly one integer — the number of good subsequences taken modulo 109+7

.

Examples
Input
Copy
2
1 2
Output
Copy
3
Input
Copy
5
2 2 1 22 14
Output
Copy
13
Note

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}

.

Note, that some subsequences are listed more than once, since they occur in the original array multiple times.

 

题意 : 给你 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
", 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;
}

 



以上是关于dp - 递推的主要内容,如果未能解决你的问题,请参考以下文章

HDU 2501 [Tiling_easy version] 递推

poj 2229 完全背包dp递推dp

FZU 2129 子序列个数 (递推dp)

动态规划(DP),递推

D. Caesar's Legions 背包Dp 递推DP

dp - 递推