51nod 1202不同子序列个数(dp)

Posted zhangbuang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\\n", (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\\n", dp[n]);
    return 0;


  







以上是关于51nod 1202不同子序列个数(dp)的主要内容,如果未能解决你的问题,请参考以下文章

51nod 1202不同子序列个数(dp)

51NOD 1202 子序列个数 DP

51nod 1202 线性dp

51nod 1202 子序列个数

51nod1202 子序列个数

1202 子序列个数(DP)