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 }