時間限制:10000ms
單點時限:1000ms
記憶體限制:256mb
描述給定乙個包含n個整數的陣列a=[a1, a2, ... an]。小ho想將a拆分成若干連續的子陣列,使得每個子陣列中的整數都是兩兩不同的。
在滿足以上條件的前提下,小ho想知道子陣列數量最少是多少。
同時他還想知道,在數量最少的前提下有多少中不同的拆法。
例如對於[1, 2, 3, 1, 2, 1],最少需要3個子陣列。有5種不同的拆法:
[1], [2, 3, 1], [2, 1]
[1, 2], [3, 1], [2, 1]
[1, 2], [3, 1, 2], [1]
[1, 2, 3], [1], [2, 1]
[1, 2, 3], [1, 2], [1]
輸入第一行包含乙個整數n。
第二行包含n個整數a1, a2, ... an。
對於30%的資料,滿足1 ≤ n ≤ 10
對於60%的資料,滿足1 ≤ n ≤ 1000
對於100%的資料,滿足1 ≤ n ≤ 100000, 1 ≤ ai ≤ 100000
輸出輸出兩個整數。第乙個表示子陣列最少的數量,第二個表示在數量最少的前提下有多少種拆法。
由於拆法可能非常多,你只需要輸出答案除以1000000007的餘數。
樣例輸入
6 1 2 3 1 2 1
樣例輸出
3 5分析:從左往右掃瞄, 找出最少的分組情況,然後dp 設 d[i] 為 (以最少分組情況考慮 )1~i 能有幾種分法。d[i] = sum(d[j] 滿足條件的j).
#include#include#include#include#includeconst int maxn = 1000000;
const int inf = 1e9;
const long long int mod = 1000000007;
typedef long long ll;
using namespace std;
int n,a[maxn+5],l[maxn+5],r[maxn+5],last[maxn+5];
int l[maxn+5],r[maxn+5],cnt;
ll d[maxn+5];
int main()
else
}memset(d,0,sizeof(d));
r[cnt] = n;
d[0] = 1, l[cnt+1] = r[cnt+1] = n+1;// d[i]表示 1~i 以最少分組的情況考慮 能有分幾齣種。
for(int i=1; i<=cnt; i++)//(l[i-1],r[i-1]) x1 x2 x3... (l[i],r[i]) y1 y2 y3 ... (l[i+1],r[i+1])./ d[yi] = sum(d[xj] 滿足條件的).
{s = r[i-1], cot = 0, maxl = -1;
for(int j=l[i];j<=r[i];j++) s = max(s,l[j]);//在 (l[i],r[i])中找出 開始的 最左符合邊界。
for(int j=s; j
hihocoder 字尾陣列
時間限制 5000ms 單點時限 1000ms 記憶體限制 256mb 描述小hi平時的一大興趣愛好就是演奏鋼琴。我們知道乙個 旋律被表示為長度為 n 的數構成的數列。小hi在練習過很多曲子以後發現很多作品自身包含一樣的旋律。旋律是一段連續的數列,相似的旋律在原數列可重疊。比如在1 2 3 2 3 ...
hihoCoder 1661 陣列區間
給出 1 到 n 的乙個排列 n le 10 5 記做 a 1,a 2,dots,a n 注 原題面表述為 給定 n 個互不相同且不超過 n 的整數 並未指明 a i 是正數,屬描述不確切,實際題意如此。見管理員賽後發的題解 求所有可能的區間中前 k k le min n,50 大的數之和的總和,對...
B 迴圈陣列 HihoCoder 1704
hihocoder 1704 給定包含n個整數的陣列a1,a2,an,你可以選擇任意乙個ai,將ai旋轉到陣列第一項,即將陣列變成 ai,ai 1,ai 2,an,a1,a2,ai 1 現在小hi希望旋轉之後的陣列滿足 對於任意k 1 i n 前k項的和都是正數。例如對於a 3,5,2,2,3,0 ...