1. 程式人生 > >51nod 1202 線性dp

51nod 1202 線性dp

png mod 當前 too lld ges def sta ace

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1202

1202 子序列個數技術分享

題目來源: 福州大學 OJ 基準時間限制:1 秒 空間限制:131072 KB 分值: 40 難度:4級算法題 技術分享 收藏 技術分享 關註 子序列的定義:對於一個序列a=a[1],a[2],......a[n]。則非空序列a‘=a[p1],a[p2]......a[pm]為a的一個子序列,其中1<=p1<p2<.....<pm<=n。 例如4,14,2,3和14,1,2,3都為4,13,14,1,2,3的子序列。對於給出序列a,有些子序列可能是相同的,這裏只算做1個,請輸出a的不同子序列的數量。由於答案比較大,輸出Mod 10^9 + 7的結果即可。 Input
第1行:一個數N,表示序列的長度(1 <= N <= 100000)
第2 - N + 1行:序列中的元素(1 <= a[i] <= 100000)
Output
輸出a的不同子序列的數量Mod 10^9 + 7。
Input示例
4
1

一眼望去令f[i]表示以a[i]結尾的子序列個數,f[i]=SUM{f[j] | a[j]!=a[i] } 累加求和就是答案。
可以維護一個計算過的fi的總和,減去之前出現過這個數的fi就是當前的f的值。
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define LL long long
 4 LL mod=1e9+7;
 5 LL f[100005];
 6 LL tmp[100005];
 7 int a[100005];
 8 int main()
9 { 10 int N,i,j,k; 11 cin>>N; 12 for(i=1;i<=N;++i) 13 { 14 scanf("%d",a+i); 15 } 16 f[0]=1; 17 LL s=1,ans=0; 18 for(i=1;i<=N;++i) 19 { 20 f[i]=(mod-tmp[a[i]]+s)%mod; 21 tmp[a[i]]=(tmp[a[i]]+f[i])%mod; 22 s=(s+f[i])%mod;
23 ans=(ans+f[i])%mod; 24 } 25 printf("%lld\n",ans); 26 return 0; 27 }

51nod 1202 線性dp