51nod 1202 子序列个数
设 \(dp[i]\) 为第i个数不同子序列个数,先不考虑重复的情况,每个数只有选不选,转移方程为 \(dp[i]=dp[i-1]\times 2\),但现在我们要求的是不同的子序列个数,因此要减去重复的子序列个数。对于选取了 \(a_i\) 的子序列,会出现重复的序列一定是以某一个满足 \(a_j=a_i\) 的 \(a_j\) 结尾的,那么重复的子序列个数就是 \(dp[j-1]\),其中 \(j\) 是最大的满 \(a_j=a_i\) 并且 \(j<i\) 的数。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+10;
const int mod=1e9+7;
int n,m;
ll dp[N];
map<ll,ll> a;
ll b[N];
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++){
cin>>b[i];
}
dp[0]=1;
for(int i=1;i<=n;i++){
dp[i]=(dp[i-1]*2-dp[a[b[i]]-1]+mod)%mod;
a[b[i]]=i;
}
cout<<dp[n]-1;
return 0;
}