fzuoj Problem 2129 子序列個數

http://acm.fzu.edu.cn/problem.php?pid=2129php

Problem 2129 子序列個數

Accept: 162    Submit: 491
Time Limit: 2000 mSec    Memory Limit : 32768 KB

 Problem Description

子序列的定義:對於一個序列a=a[1],a[2],......a[n]。則非空序列a'=a[p1],a[p2]......a[pm]爲a的一個子序列,其中1<=p1<p2<.....<pm<=n。ios

例如4,14,2,3和14,1,2,3都爲4,13,14,1,2,3的子序列。spa

對於給出序列a,請輸出不一樣的子序列的個數。(因爲答案比較大,請將答案mod 1000000007)設計

 Input

輸入包含多組數據。每組數據第一行爲一個整數n(1<=n<=1,000,000),表示序列元素的個數。code

第二行包含n個整數a[i] (0<=a[i]<=1,000,000)表示序列中每一個元素。blog

 Output

輸出一個整數佔一行,爲所求的不一樣子序列的個數。因爲答案比較大,請將答案mod 1000000007。

 Sample Input

4 1 2 3 2

 Sample Output

13

 Hint

其中40%數據點1<=n<=1000。

 Source

福州大學第十屆程序設計競賽
 
分析:

給定一個字符串,求出該字符串有多少個不一樣的子序列ip

定義dp[k]爲前k個字符中子序列的個數字符串

那麼dp[k]來自於兩種狀態,string

dp[k]=2*dp[k-1]+1;若是a[k]與前k-1個字符都不相同it

dp[k]=2*dp[k-1]-dp[t-1],若是a[k]與前k-1個字符有相同的,t是與之相同的最近的一個下標。

 

AC代碼:

 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<string.h>
 5 #define N 1000050
 6 #define mod 1000000007
 7 using namespace std;
 8 int a[N],b[N];
 9 long long dp[N];
10 int main()
11 {
12     int n,i,j;
13     while((scanf("%d",&n))!=EOF)
14     {
15         for(i=1;i<=n;i++)
16             scanf("%d",&a[i]);
17         memset(b,0,sizeof(b));
18         memset(dp,0,sizeof(dp));
19         for(i=1;i<=n;i++)
20         {
21             if(b[a[i]]==0)
22                 dp[i]=(dp[i-1]*2+1)%mod;
23             else
24                 dp[i]=(dp[i-1]*2-dp[b[a[i]]-1]+mod)%mod;
25             b[a[i]]=i;
26         }
27         printf("%lld\n",dp[n]%mod);
28     }
29     return 0;
30 
31 }
相關文章
相關標籤/搜索