1. 程式人生 > 其它 >二分法求LIS

二分法求LIS

二分法求LIS的本質並不是二分,而是儲存整個序列資料的陣列f[n]。

我們考慮到,f[i]實際上是長度為i的上升序列的"最後一個值",那麼我們把他們擬人化,看看他們自己希望怎麼更新。

假設我是f[3]=4,我的好朋友是f[4]=6。那麼,如果“我”可以通過拓展一個大於我末尾的數字來更新自己,那我肯定是希望自己最後長得儘量長。

換句話講,我現在的大小為4,長度為3;朋友的大小為6,長度為4。

假設不考慮其他人,只考慮對“我”和“朋友”進行更新,然後提供了一個為5的值。

這時我們發現,我可以通過這個值升級到長度為4,而且朋友的"DNA"不如我的優秀,因為從貪心的角度考慮,我能繼續更新的“概率”必然是大於朋友的。因此,此時進行優勝劣汰,讓我的“複製體”替代好朋友,即f[4]=5。

單調遞增的性質很容易證明:f[1]就是min{f[i]},而f[2]必須大於f[1]才能更新,以此類推。

那麼,剩下的問題就在於,二分到某個位置,並進行上述所說的更新後,會不會沒有更新完全?換句話講,後面或者前面可能還有一大堆序列需要更新,但我們只更新了一個,這樣會不會導致答案出現嚴重問題?

對於前面的序列,可想而知一定比我們小,那我們設身處地地想一下,我們是f[2]=1和f[3]=2,此時有個100來問我要不要更新自己,那f[2]肯定不樂意更新,f[3]更不樂意,只有確實有可能“接受”這個數字的“人”,才能更新。比如提供一個Interger.MAX_VALUE,肯定只能更新f[m+1](m為求解過程中當前求到的LIS長度(非最終答案))。

那對於後面的序列呢?不好意思,你確實“有可能更新”,可是問題在於,你的“政治位置”不夠精準,“資格不夠老”,不能更新。

比如目前是f[4]=10,f[5]=20,f[6]=30,嘗試更新一個15,問題在於既然f[5]=20,那麼對於長度為6的序列來說,他能找到的最好的“女朋友”(長度為5的最優序列),第5個數字最小也得是20,15是沒辦法排在他後面的。因此,我們如果想要“改革”,只能慢慢做起(先更新一個數字,慢慢轉化全域性)。