簡體   English   中英

DP:最長遞增子序列的思考過程和解決方案

[英]DP: Longest Increasing Subsequence Thought Process & Solution

對於最長增長子序列問題,我設想保留一個DP數組,該數組始終應將最大值保留在最遠端。 看起來像這樣的東西:

{1, 1, 2, 3, 3, 4, 5, 6, 6, 6}

為了產生第一個不正確的解決方案,我所遵循的思考過程是,我們希望僅從第一個元素開始查看整個數組,計算LIS,然后將值遞增地添加到數組的末尾。 在執行此操作時,我們將DP數組中的LIS增量計算為舊子數組的LIS加上我們添加的新元素。 這意味着在dp數組的索引i處存在長度為i的子數組的LCS的值。

更明確地說

array => {5, 6, 7, 1, 2, 3, 4}
dp    => {1, 2, 3, 3, 3, 3, 4}

這樣,DP陣列的最后一個條目將是當前陣列的LIS。 這將成為我們的不變式,因此,當我們達到終點時,可以確保最后的值是我們唯一需要的值。 然后讓我想到,在遍歷具有DP類感覺的數組時,下一個值不依賴於該數組中以前列出的任何值,因此此方法與維護maxLIS變量(一種模式)相同我已經在許多O(n)解決方案中看到過。 因此,我最接近正確的解決方案如下:

1.)將輸入數組/向量的副本保存為old

2.)對原始輸入數組進行排序

3.)遍歷排序后的數組,每當下一個值(該值應大於當前值)出現在原始數組中的當前值之前,變量就longest遞增一個。

4.)返回longest

代碼是〜this:

int lengthOfLIS(vector<int>& seq) {
  if (!seq.size()) return 0;
  vector<int> old = seq;

  sort(seq.begin(), seq.end());

  int longest = 1;

  for (int i = 1; i < seq.size(); ++i) {
    if (seq[i] > seq[i-1] && find(old.begin(), old.end(), seq[i]) - old.begin() > find(old.begin(), old.end(), seq[i-1]) - old.begin()) longest++;
  }
  return longest;
}

在使用find方法的情況下(我假設是線性操作),我們可以通過制作一個數據結構來存儲值的原始索引以及值本身來進行常量操作,因此我們無需執行任何操作遍歷以查找原始數組( old )中元素的索引。 我相信這將是一個O(nlog(n))解決方案,但是此輸入數組失敗: [1,3,6,7,9,4,10,5,6] 在這里檢查

最終,我進行了一些研究,發現我讀過的所有解決方案指南的事實都是,他們的解決方案使DP數組的值不按順序排列,而是像這樣:DP數組中的值表示遞增的長度子序列,該子序列的最后一個值是originalArray[index]的值。

更明確地說,

array => {5, 6, 7, 1, 2, 3}
dp    => {1, 2, 3, 1, 2, 3}

此處,其中5是遞增子序列的最后一個值,在它之前沒有值,因此它的長度必須為1。如果6是遞增子序列的最后一個值,我們必須查看它之前的所有值以確定a以6結尾的子序列即可。 它之前只能有5個,因此是到目前為止增加的最長子序列2。這將繼續,您將在DP數組中返回最大值。 該解決方案的時間復雜度為O(n^2) ,即標准天真解決方案。

問題:

我很好奇如何正確思考這個問題。 我想微調我的思維過程,以便我可以從頭開始提出一個最佳解決方案(至少是目標),所以我想知道

1.)這個問題的什么屬性應該觸發我使用與使用它不同的DP陣列? 事后看來,我的原始方式僅相當於保留max變量,但即使那樣,我仍然很難看到該問題的性質,這會觸發思想“嘿,我的DP數組中索引為i的條目的值應該是以originalArray [i]結尾的遞增子序列。 我正在努力查看該如何解決。

2.)是否可以使我建議的O(nlog(n))解決方案正常工作? 我知道存在O(nlog(n))解決方案,但是由於我無法正常工作,因此我認為我需要朝正確的方向輕推。

我承認,這是一個有趣的問題,我沒有確切的答案,但是我想我可以向您介紹正確的方向。 所以就這樣:

面對這樣的困境,我通常會轉向基礎知識。 就像您的情況一樣,請經過動態編程的定義。 它具有兩個屬性:

  1. 重疊子問題
  2. 最佳子結構。

您可以輕松找到標准解決方案中反映的這些屬性,但您的卻不是。 您可以在cormen中閱讀有關它們的信息,也可以在DP的上下文中對其進行谷歌搜索。

我認為您的解決方案不是DP,您只是找到了某種模式,並且您正在嘗試根據該模式進行解決。 如果您沒有得到解決方案,則意味着您的模式錯誤或解決方案無所適從。 在這種情況下,請嘗試從數學上證明您正在觀察的模式是正確的,並證明該解決方案也應該有效。

在我研究您的解決方案時,請給我更多時間,但同時您也可以嘗試為您的解決方案開發證明。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM