FZU 2129 子序列个数 (递推dp)

题目链接:http://acm.fzu.edu.cn/problem.php?pid=2129

dp[i]表示前i个数的子序列个数

当a[i]在i以前出现过,dp[i] = dp[i - 1]*2 - dp[pre - 1],pre表示a[i]在i之前的位置

当a[i]在i以前没有出现过,dp[i] = dp[i - 1] *2 + 1

 1 //#pragma comment(linker, "/STACK:102400000, 102400000")
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <cstdlib>
 5 #include <cstring>
 6 #include <cstdio>
 7 #include <vector>
 8 #include <cmath>
 9 #include <ctime>
10 #include <list>
11 #include <set>
12 #include <map>
13 using namespace std;
14 typedef long long LL;
15 typedef pair <int, int> P;
16 const int N = 1e6 + 5;
17 LL dp[N], mod = 1e9 + 7, pre[N];
18 
19 int main()
20 {
21     int n, num;
22     while(~scanf("%d", &n)) {
23         memset(pre, 0, sizeof(pre));
24         for(int i = 1; i <= n; ++i) {
25             scanf("%d", &num);
26             if(pre[num]) {
27                 dp[i] = ((dp[i - 1]*2 - dp[pre[num] - 1]) % mod + mod) % mod;
28             } else {
29                 dp[i] = (dp[i - 1]*2 + 1) % mod;
30             }
31             pre[num] = i;
32         }
33         printf("%lld\n", dp[n]);
34     }
35     return 0;
36 }

 

posted @ 2016-09-16 15:22  Recoder  阅读(175)  评论(0编辑  收藏  举报