zoukankan      html  css  js  c++  java
  • 51nod 1202不同子序列个数(dp)

    子序列的定义:对于一个序列a=a1 ,a2 ,......an 。则非空序列a'=app1 ,app2 ......appm 为a的一个子序列,其中1<=p1<p2<.....<pm<=n。
    例如4,14,2,3和14,1,2,3都为4,13,14,1,2,3的子序列。对于给出序列a,有些子序列可能是相同的,这里只算做1个,请输出a的不同子序列的数量。由于答案比较大,输出Mod 10^9 + 7的结果即可。
     

    Input第1行:一个数N,表示序列的长度(1 <= N <= 100000)
    第2 - N + 1行:序列中的元素(1 <= ai <= 100000)Output输出a的不同子序列的数量Mod 10^9 + 7。Sample Input

    4
    1
    2
    3
    2

    Sample Output

    13
    Solution:
    设以第i位为结尾且一定选的方案数
    一片题解:
    https://www.cnblogs.com/acerkoo/p/11621037.html
    #include <cstdio>
    
    using namespace std;
    
    const int maxn = 1e5+10;
    const int mod = 1e9+7;
    
    int last[maxn];
    int dp[maxn], pre[maxn];
    int n, a[maxn];
    
    int main() {
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i)
            scanf("%d", a+i);
    
    //    思路一:
    //    pre[0] = 1;
    //    for (int i = 1; i <= n; ++i) {
    //        if(last[a[i]] == 0) dp[i] = pre[i-1];
    //        else dp[i] = (pre[i-1]-pre[last[a[i]]-1]+mod)%mod;
    //        pre[i] = (pre[i-1] + dp[i]) % mod;
    //        last[a[i]] = i;
    //    }
    //    printf("%d
    ", (pre[n]-1+mod)%mod);
    
    //  思路二:
        dp[1] = 1, last[a[1]] = 1;
        for (int i = 2; i <= n; ++i) {
            if(last[a[i]] == 0) dp[i] = (dp[i-1]*2%mod+1)%mod;
            else dp[i] = (dp[i-1]*2%mod-dp[last[a[i]]-1]+mod)%mod;
            last[a[i]] = i;
        }
    
        printf("%d
    ", dp[n]);
        return 0;
    }
    
    
    

      







  • 相关阅读:
    Understanding Convolutions
    ckeditor粘贴word图片自动上传控件
    csharp如何切片处理视频大文件
    .net如何切片处理视频大文件
    asp.net如何切片处理视频大文件
    c#如何切片处理视频大文件
    java如何切片处理视频大文件
    jsp如何切片处理视频大文件
    php如何切片处理视频大文件
    java大文件(百M以上)的上传下载讨论
  • 原文地址:https://www.cnblogs.com/zhangbuang/p/11624259.html
Copyright © 2011-2022 走看看