• 51nod 1202 不同子序列个数 [计数DP]


    1202 子序列个数
    题目来源: 福州大学 OJ
    基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
    收藏
    关注
    子序列的定义:对于一个序列a=a[1],a[2],......a[n]。则非空序列a'=a[p1],a[p2]......a[pm]为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 <= a[i] <= 100000)
    
    Output
    
    输出a的不同子序列的数量Mod 10^9 + 7。
    
    Input示例
    
    4
    1
    2
    3
    2
    
    Output示例
    
    13
    

    dp[i]为前i个字符中子序列的个数
    当a[i]没有出现过的时候,dp[i] = dp[i-1]*2 + 1,因为相当于在dp[i-1]个子序列中新增一个a[i],再加上它本身。
    当a[i]出现过的时候就要去重,减去以a[i]以前出现的位置的前一位子序列的个数=dp[vis[ a[i] ] - 1],因为a[i]为结尾重复了。

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int N = 1e5+5;
    const int  mod  = 1000000007;
    
    int a[N];
    ll dp[N]; //dp[i]为前i个字符中子序列的个数
    int vis[N];
    int main()
    {
        int n;
        while(cin >> n){
            for(int i=1;i<=n;i++){
                cin >> a[i];
            }
            memset(dp,0,sizeof(dp));
            memset(vis,0,sizeof(vis));
            dp[1]=1;
            vis[a[1]]=1;
            for(int i=2;i<=n;i++){
                if(vis[a[i]]==0){
                    dp[i] = (dp[i-1]*2 + 1)%mod;
                }else{
                    dp[i] = (dp[i-1]*2 - dp[ vis[a[i]] - 1 ] + mod) % mod;
                }
                vis[a[i]]=i; //标记a[i]出现的位置
            }
            cout<<dp[n]<<endl;
        }
        return 0;
    }
            // 1 2 3 2
            //13
    
    
    
  • 相关阅读:
    Flask第二篇——服务器相关
    Flask第一篇——URL详解
    Appium 定位方法例子(4)
    selenium 上传文件方法补充——SendKeys、win32gui
    Appium+python (3) 异常处理
    Appium+python (3) 元素定位(1)
    "http://127.0.0.1:4723/wd/hub"的解释
    Appium + Python App自动化(2)第一个脚本
    Appium+python(1)简单的介绍环境搭建
    用fiddler设置手机代理
  • 原文地址:https://www.cnblogs.com/Roni-i/p/9003459.html
Copyright © 2020-2023  润新知