fzu2129 子串行個數 計數dp

2021-09-20 21:27:57 字數 857 閱讀 5803

給n(n<=1e6)個數,統計所有不同子串行的個數

第i個數個數ai(0<=ai<=1e6),答案mod 1e9+7

last[v]表示v上一次出現的位置

dp[i]表示到i為止,所有本質不同子串行的個數

考慮a[i],

①如果a[i]沒有出現過,那麼dp[i]至少為dp[i-1],在dp[i-1]每個子串行後補a[i]可以得到新的dp[i-1]個子序列,

再加上長度為1的a[i]這個子串行,就是答案

②如果a[i]沒有出現過,那麼dp[i]至少為dp[i-1],在dp[i-1]每個子串行後補a[i]可以得到新的dp[i-1]個子序列,

而這其中是有算重複的,算重了dp[last[a[i]]-1]個,在last[i]位置時就因為補了乙個last[a[i]]導致多了dp[last[a[i]-1]個子序列

而且由於之前出現過,這個長度為1的a[i]也不能算,所以此處不加1,還要減去dp[last[a[i]-1]

還是感覺計數dp好難啊……

#include#include#include#includeusing namespace std;

typedef long long ll;

const int mod=1e9+7;

const int maxn=1e6+10;

int n,v;

int last[maxn];//last[v]表示v這個值上一次出現的位置

int dp[maxn];//dp[i]表示到[1,i]所有本質不同子串行的個數

int main()

printf("%d\n",dp[n]);

}return 0;

}

FZU 2129 子串行個數

給乙個序列,裡面可能有相同元素,問能組成多少不同子串行。dp。一直想用dp i 表示到序列a1 ai的答案,一直想不出來,其實有更好的做法。我們可以用dp i 表示最後乙個元素為ai的子串行有多少,sum i 表示dp 1 dp i 的和。狀態轉移見 include include include ...

FZU2129 子串行個數 DP

題目大意 求一串行的不相同的子串行的個數。分析 注意區分子序列和子串的區別 子串行可以不連續,子串必須連續。先說說本題吧。我們用dp i 來紀錄以 前i個字元組成的序列 的不同子串行的個數,很顯然,對於dp i 1 我們把第i 1個字元str i 1 分別加到前面已經有的子串行中,這樣就又多出了dp...

FZU 2129 子串行個數 動態規劃

題意 子串行的定義 對於乙個序列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,請輸出不同的子串行的個數。由於答案比較大,請將答案mod 1000000...