動態規劃經典問題 最長上公升子串行poj2533

2021-08-07 07:56:53 字數 1268 閱讀 9512

這裡我們拆分出的子問題不是n個數的最長公共子串行的長度,而是以sta[i]的值為結尾的最長公共子串行的長度。

舉個例子啊,比如1 6 1,n個數的最長公共子串行的長度是2(這個序列是1 6)(這也就是最終答案),而以sta[i]為結尾的最長公共子串行長度是1(這個序列是1)。

因為知道了這個以每個數結尾的公共子串行長度,n個、n-1個數、n-2的序列的最長公共子串行的長度也就能算出來了(取這些長度的最大值即可),換句話說,只是知道n-1個數的最長公共子串行的長度是求不出來n個數的最長公共子串行長度的。因為你不知道前n-1個數的最長公共子串行的結尾的數的值是多少,也就沒法比較sta[n]和結尾數值的大小,也就沒法求n個數的最長公共子串行長度。

好,那麼子問題就是以

sta[i]

的值為結尾的最長公共子串行的長度

了。從頭往後dp還是從後往前dp呢?

想啊,我們想知道以第n個數為結尾的子問題答案,得知道所有從1到n-1

個數的子問題的答案吧?因為要滿足「上公升」這個條件啊,得比較sta[n]和前面所有子問題結尾的值啊。

所以從頭往後dp。

下面我模擬一下這個dp過程。

到了第i個數了。 首先從前面所有子問題中找出乙個結尾值比第i個數小的而且最大的長度(maxlen),然後把這個第i個數加到這個序列裡面去,也就是dp[i]=maxlen+1;

dp這個陣列用來存子問題的答案,dp[3]就是存以sta[3]這個值為結尾的當前最長公共子串行的長度。sta這個陣列存原來數列的值。

ac**

#include #include #include #include #include #include #include #include #include using namespace std;

const int maxn=1e4+10;

const int inf=0x3f3f3f3f;

int sta[maxn];//存這個序列的每個數

int dp[maxn];//存子問題的答案

int n;

int main()

}

//把sta[i]這個數加到這個序列當中去,dp[i]也就是maxlen+1這個值。

dp[i]=maxlen+1;

}

//最後從所有子問題中找到乙個最長的序列(這個序列並不一定要以第n個數結尾)

int ans=-1;

for(int i=1;i<=n;i++)

if(ans

經典動態規劃問題 最長上公升子串行 LIS

目錄 最長上公升子串行 o n 2 動態規劃 o n logn 貪心 二分 乙個數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a1,a2,an 我們可以得到一些上公升的子串行 ai1,ai2,aik 這裡1 i1 i2 ik n。狀態 dp i 表示以a i ...

動態規劃 最長上公升子串行問題

原文 主題 動態規劃 最長上公升子串行問題,也就是longest increasing subsequence,縮寫為lis。是指在乙個序列中求長度最長的乙個上公升子串行的問題,是動態規劃中乙個相當經典問題。在這裡我們可以看到,這個上公升實質上就是乙個對 進行定義的過程,所以我們求解的其實是一類問題...

最長上公升子串行問題(動態規劃)

乙個數的序列bi,當b1 n。比如,對於序列 1,7,3,5,9,4,8 有它的一些上公升子串行,如 1,7 3,4,8 等等。這些子串行中最長的長度是4,比如子串行 1,3,5,8 你的任務,就是對於給定的序列,求出最長上公升子串行的長度。輸入輸入的第一行是序列的長度n 1 n 1000 第二行給...