用動態規劃來解決最長上公升子串行問題的需要注意:
遞迴到動規的一般方法:遞迴函式有n個引數,就定義乙個n維的陣列,陣列的下標是遞迴函式引數的取值範圍,陣列元素的值是遞迴函式的返回值,這樣就可以從邊界值開始,逐步填充陣列,相當於計算遞迴函式值的逆過程。
在最長上公升子串行問題中,假設序列為 a1, a2 …, ak, …, an,想要通過動規的方式來求解,子問題是求以 ak為終點的最長子序列,記為maxlen(k),則求以 ak+1為終點的最長子序列可以通過以 a1, …, ak中的點(該點的值小於 ak)作為終點的最長子序列的最大值加上1求出來。因此問題具有最優子結構性。且在上述求解下乙個狀態值的過程中只與當前狀態值有關,與如何到達當前狀態無關,因此具有無後效性。
下面貼出通過建立備忘的遞迴方法以及直接遞推求解問題的**。
/*建立備忘的遞迴方法*/
#include
#include
using
namespace
std;
int maxlen(int);
/*a1, a2, ..., ak, ..., an為一串行
以ak為終點的最長子序列即為maxlen(k)
遞推公式:
k!=1 =>
maxlen(k) = max
a = (int *)malloc((n + 1) * sizeof(int));
if(a == null)
for(int i = 1; i < n + 1; i++)
int max = 0, len_i;
for(int i = 1; i < n + 1; i++)
if(len_i > max)
max = len_i;
}cout
<< max << endl;
return0;}
int maxlen(int k)
else
}maxlen[k] = max;
return max;
}}
/*直接遞推求解*/
#include
#include
#include
using
namespace
std;
const
int maxn = 1010;
int a[maxn];
int maxlen[maxn];
int main()
for(int i = 2; i <= n; ++i)
//max_element返回陣列中最大的元素,左閉右開
cout
<< *max_element(maxlen + 1, maxlen + n + 1);
return
0;}
最長上公升子串行
問題描述 乙個數的序列bi,當b1 b2 bs的時候,我們稱這個序列是上公升的。對於給定的乙個序列 a1,a2,an 我們可以得到一些上公升的子串行 ai1,ai2,aik 這裡1 i1 i2 ik n。比如,對於序列 1,7,3,5,9,4,8 有它的一些上公升子串行,如 1,7 3,4,8 等等...
最長上公升子串行
最長上公升子串行問題是各類資訊學競賽中的常見題型,也常常用來做介紹動態規劃演算法的引例,筆者接下來將會對poj上出現過的這類題目做乙個總結,並介紹解決lis問題的兩個常用 演算法 n 2 和 nlogn 問題描述 給出乙個序列a1,a2,a3,a4,a5,a6,a7.an,求它的乙個子串行 設為s1...
最長上公升子串行
最長上公升子串行問題 給出乙個由n個數組成的序列x 1.n 找出它的最長單調上公升子串行。即求最大的m和a1,a2 am,使得a1動態規劃求解思路分析 o n 2 經典的o n 2 的動態規劃演算法,設a i 表示序列中的第i個數,f i 表示從1到i這一段中以i結尾的最長上公升子串行的長度,初始時...