思路:
dp[i]表示第以i个数字结尾的子序列的个数
那么在递推的过程中可能有两种情况
- 当a[i]没有出现过的时候,dp[i] = dp[i-1]*2 + 1,因为相当于在dp[i-1]个子序列中新增一个a[i],再加上它本身。
- 当a[i]出现过的时候就要去重,减去以a[i]以前出现的位置的前一位子序列的个数,因为a[i]为结尾重复了。
注意:每次要更新每一个数字出现的位置。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 100005;
const int mod = 1000000007;
typedef long long LL;
int n;
int a[maxn];
int vis[maxn];
LL dp[maxn];
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d",&n);
for(int i = 1;i <= n; i++) {
scanf("%d",&a[i]);
}
memset(dp,0,sizeof(dp));
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;
}
printf("%I64d\n",dp[n]);
return 0;
}