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;
}

  







原文地址:https://www.cnblogs.com/zhangbuang/p/11624259.html