子串行的個數

2021-09-10 14:27:24 字數 1387 閱讀 9562

子串行的定義:對於乙個序列a=a[1],a[2],......a[n]。則非空序列a'=a[p1],a[p2]......a[pm]為a的乙個子串行,其中1<=p1例如4,14,2,3和14,1,2,3都為4,13,14,1,2,3的子串行。對於給出序列a,有些子串行可能是相同的,這裡只算做1個,請輸出a的不同子串行的數量。由於答案比較大,輸出mod 10^9 + 7的結果即可。

輸入

第1行:乙個數n,表示序列的長度(1 <= n <= 100000)

第2 - n + 1行:序列中的元素(1 <= a[i] <= 100000)

輸出

輸出a的不同子串行的數量mod 10^9 + 7。
輸入示例

412

32

輸出示例

13
解題思路:(51nod)

假設dp[i]表示前i項形成的子串行(含空)的個數。下標從1開始,初值是dp[0] = 1,對應代表空子序列。我們考慮第i項,如果所有的數都不相等,應該有dp[i] = dp[i – 1] * 2,其實就是考慮把第i個數放到最後或者不放到最後的情況。

然而,因為有可能有相同的數,我們假設第i個數出現之前最近的在j (j < i)位置也出現過,那麼實際上我們這種簡單*2會有重複,哪些子串行重複呢? 我們設數列為a, 並且下標從1開始。

原來恰好以第j個數結尾的那些被我們算了兩次,因為以第j個數結尾可以換成以第i個數結尾是一樣的。如何計算出這個數的個數呢? 其實這個數等於dp[j – 1],因為前面(j – 1)個數的子串行最後跟上第j個數就可以了。

於是我們有了遞推式:

dp[i] = dp[i – 1] * 2  如果a[i]不在之前出現

dp[i] = dp[i – 1] * 2 – dp[j – 1],如果a[i]最近在j的位置出現過。

ac**:

#includeusing namespace std;

const int maxn=1e5+10;

const int mod=1e9+7;

typedef long long ll;

ll a[maxn],vis[maxn],dp[maxn];

int main()

dp[0]=1;

for(int i=1;i<=n;i++)

vis[a[i]]=i;

} cout<}

子串行的個數

龐果網題目 子串行的定義 對於乙個序列a a 1 a 2 a n 則非空序列a a p1 a p2 a pm 為a的乙個子串行,其中1 p1 還是靠動態規劃 設f k 為前k個數的子串行數目,則f 0 1 f k 與f k 1 有什麼關係呢?例如序列,k 2時的子串行有 0 1 2 01 02 12...

(子串行)2504 是子串行的個數

2 秒262,144 kb 20 分 3 級題 小b有乙個字串s和n個字串words 1.n 現在她想知道有多少個i滿足words i 是s的子串行。樣例解釋 a,acd,ace都是abcde的子串行,但bb不是。收起第一行輸入乙個由小寫字母組成的字串s 第二行輸入乙個數n 之後n行每行乙個字串,表...

1202 子串行個數

1202 子串行個數 子串行的定義 對於乙個序列a a 1 a 2 a n 則非空序列a a p1 a p2 a pm 為a的乙個子串行,其中1 p1例如4,14,2,3和14,1,2,3都為4,13,14,1,2,3的子串行。對於給出序列a,有些子串行可能是相同的,這裡只算做1個,請輸出a的不同子...