51nod 1056 最長等差數列 V2

2021-08-08 23:16:21 字數 2038 閱讀 3554

這個和1055那個題差不多,稍微改改就過了,首先是剪枝的改寫,這個剪枝是必過的,唐老師在討論裡進行了證明。

首先要明確等差數列的定義。

乙個等差數列可以用首項、公差和項數的三元組  (

firs

t,de

lta,

leng

th)

表示,當然這個  f

irst

也可以換成末項  l

ast

,取決於你的演算法。

我們要考慮的等差數列要盡量用少的資訊表示所有的可能,也就是說提取出來的等差數列之間不能有相互包含的關係,例如  (

2,3,

4)和  (

2,3,

5)就冗餘了,而  (

2,3,

4)和  (

5,3,

4)也是冗餘的,因為當它們出現在同乙個序列裡時,  (

2,3,

5)也是存在的。

因此我們只需要考慮滿足  (

firs

t−de

lta)

這個數字不存在,並且  (

last

+del

ta)

這個數字不存在的等差數列。

接下來要發現這樣的等差數列在  k

充分大時是不多的。

定義:集合裡的兩個元素是足夠相鄰的,當且僅當它們的排名之差不超過  n

k−1

。由鴿巢原理可知,乙個長度為  k

的等差數列必然包含至少  k

−12

對足夠相鄰的元素(考慮等差數列裡排名最小的和排名最大的那兩個元素)。

而集合裡足夠相鄰的元素對數不超過  n

22(k

−1)

,我們所求的不同等差數列也不會包含相同的一對足夠相鄰的元素,所以我們能得到的等差數列數量是不超過  n

2(k−

1)2

的。最後要利用這個性質來構造相應的演算法。

利用數量不多的性質,我們可以嘗試找出所有長度至少為 200 的等差數列,從中選取最長的那個。

注意到上面的證明利用到了集合的大小,類似地也可以證明,這樣的等差數列必然有  ⌊

k2⌋

項在前  ⌊

n2⌋

小的元素集合裡,或者有  ⌊

k2⌋

項在前  ⌈

n2⌉

大的元素集合裡。

而集合大小減半同時數列項數減半對數列數量的影響是不大的,所以可以嘗試對集合分治,分別找出更小情況的解,然後放到大的集合裡嘗試向左向右  o

(k)

擴張,再進行去重,從而得到當前情況的解。

不妨設  t

(n,k

)

表示從大小為  n

的集合裡提取長度至少為  k

的不同等差數列的複雜度,則有  t

(n,k

)=2t

(n2,

k2)+

o(n2

k2k)

⇒t(n

,k)=

o(n2

klognk

)

。其次,就是hash這個hash要手打,hash就是把之前的dp陣列給換掉。暴力的去查詢。最後,我想說的是,花了130個點頭盾,以為能上第一,誰知道上了第二。**還是發了吧。。。。

#include#include#define ll long long

using namespace std;

const int mod=233333;

int a[50010],ha[mod],ans=199,last[50010],n;

int read()

void add(int k,int i)

bool find1(int k)

int main()}}

//cout<=200)

printf("%d\n",ans);

else printf("no solution\n");

return 0;

}

51nod1056 最長等差數列 V2

1056 最長等差數列 v2 基準時間限制 8 秒 空間限制 131072 kb n個不同的正整數,從中選出一些數組成等差數列。例如 1 3 5 6 8 9 10 12 13 14 等差子數列包括 僅包括兩項的不列舉 1 3 5 1 5 9 13 3 6 9 12 3 8 13 5 9 13 6 8...

51Nod 最長等差數列

題目描述 n個不同的正整數,找出由這些數組成的最長的等差數列。例如 1 3 5 6 8 9 10 12 13 14 等差子數列包括 僅包括兩項的不列舉 1 3 5 1 5 9 13 3 6 9 12 3 8 13 5 9 13 6 8 10 12 14 其中6 8 10 12 14最長,長度為5。輸...

51nod 1055 最長等差數列

原題鏈結 1055 最長等差數列 基準時間限制 2 秒 空間限制 262144 kb 分值 80 難度 5級演算法題 n個不同的正整數,找出由這些數組成的最長的等差數列。例如 1 3 5 6 8 9 10 12 13 14 等差子數列包括 僅包括兩項的不列舉 1 3 5 1 5 9 13 3 6 9...