Codeforces Round #523 (Div. 2) C. Multiplicity DP
阿新 • • 發佈:2018-12-02
題意:
給n個整數的數列,你可以從中去掉一些數得到一個新的數列,新的數列是好數列當對於每一個i,a[i] %i == 0。
問你有多少個好數列
解題思路:
dp求解,二維的dp很好想,dp[i][j]表示前i個數中 因數為j 的好數列的個數,
最後的答案就是sum(i:1->n)dp[n][i] 更新也很好想到
但是這樣會MLE。注意到其實第一維是可以壓縮掉的,那麼我們更新的時候只在j為a[i]的因數才更新
即對於每一個因子 dp[j] += dp[j-1]
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int M=1e9+7; ll a[1000005]; ll dp[1000005]; int main() { ll n; while(~scanf("%lld",&n)){dp[0]=1; for(int i=1;i<=n;i++) { scanf("%lld",&a[i]);vector<ll>vec; for(int j=1;j*j<=a[i]&&j<=i;j++){ if(a[i]%j==0){ vec.push_back(j); if(j*j!=a[i]) vec.push_back(a[i]/j); } } sort(vec.begin(),vec.end());//排序 reverse(vec.begin(),vec.end());//逆序 for(int i=0;i<vec.size();i++){ ll it=vec[i];//因數為 it dp[it]+=dp[it-1]; dp[it]%=M; } } // for(int i=n;i>=1;i--) // dp[i]+=dp[i-1]; ll ans=0; for(int i=1;i<=n;i++) ans+=dp[i],ans%=M; printf("%lld\n",ans%M); } }