• Codeforces Round #523 (Div. 2) Cdp


    题:https://codeforces.com/contest/1061/problem/C

    题意:给你一个序列,我们求他们子序列的个数,这个子序列有个限制就是每一个子序列上的值都必须是能整除他的下标,问有多少个

    分析:考虑dp,我们先考虑二维的dp,定义dp[i][j]表示前i个数中,能从中提取出j个”好“序列,所以dp[i][j]就可以从dp[i-1][j-1]+dp[i-1][j]得来(前提是a[i]%j==0).显然a[i]%j!=0时dp[i][j]=dp[i-1][j]

       但这样写会MLE,所以我们将这个二维数组压缩。我们发现,我们只是在a[i]%j==0的条件下才有更新值,也就相当于前缀和,所以我们只对因子进行更新,dp[j]=dp[j]+dp[j-1]

    #include<bits/stdc++.h>
    using namespace std;
    #define pb push_back
    typedef long long ll;
    const int M=1e5+5;
    const int mod=1e9+7;
    vector<int>a[M];
    ll b[M],dp[M];
    stack<int>sta;
    void solve(int x){
        int temp=b[x];
        for(int i=1;i*i<=temp;i++){
            if(temp%i!=0)
                continue;
            if(i*i==temp)
                a[x].pb(i);
            else
                a[x].pb(i),sta.push(temp/i);
        }
        while(!sta.empty()){
            a[x].pb(sta.top());
            sta.pop();
        }
    }
    int main(){
        int n;
        cin>>n;
        for(int i=0;i<n;i++){
            scanf("%lld",&b[i]);
            solve(i);
        }
        dp[0]=1;
        for(int i=0;i<n;i++){
            for(int j=a[i].size()-1;j>=0;j--){
                int temp=a[i][j];
                if(temp<=n&&dp[temp-1]){
                    dp[temp]=(dp[temp]+dp[temp-1])%mod;
                }
            }
        }
        ll ans=0;
        for(int i=1;i<=n;i++)
            ans+=dp[i],ans%=mod;
        cout<<ans<<endl;
    }
    View Code
  • 相关阅读:
    PHP Framework
    PHP Framework
    PHP Framework
    PHP Framework
    Coursera:一流大学免费在线课程平台
    在线编译器Coding Ground
    朱子家训
    [转]3天搞定的小型B/S内部管理类软件定制开发项目【软件开发实战10步骤详解】
    [转]Android 如何监听返回键,弹出一个退出对话框
    [转]Android 完美退出 App (Exit)
  • 原文地址:https://www.cnblogs.com/starve/p/11982915.html
Copyright © 2020-2023  润新知