dp[i]代表是以i位的a[i]结尾,有多少种,(包括空集)
状态转移方程 1.如果a[i]之前没有出现过dp[i]=2*dp[i-1] 前面i-1有dp[i-1]种可能,第i个数放或不放
2.如果a[i]之前出现过:dp[i]=2*dp[i-1]-dp[mark[a[i]]-1] 减去重复的部分,mark【i】是a[i]最近一次出现的位置.
最后减一,减去空集
#include <stdio.h>
#include <string.h>
const int mod=1e9+7;
int a[100005];
int mark[100005];
long long dp[100005];
int main()
{
int n;
while(~scanf("%d",&n))
{for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
memset(dp,0,sizeof(dp));
memset(mark,0,sizeof(mark));
dp[0]=1;
for(int i=1;i<=n;i++)
{
if(mark[a[i]]==0)
{
dp[i]=(2*dp[i-1])%mod;
}
else
{
dp[i]=(2*dp[i-1]-dp[mark[a[i]]-1]+mod)%mod;
}
mark[a[i]]=i;
}
printf("%I64d\n",dp[n]-1);}
return 0;
}