最長上公升子串行問題是各類資訊學競賽中的常見題型,也常常用來做介紹動態規劃演算法的引例,筆者接下來將會對poj上出現過的這類題目做乙個總結,並介紹解決lis問題的兩個常用
演算法(n^2)和(nlogn).
問題描述:給出乙個序列a1,a2,a3,a4,a5,a6,a7....an,求它的乙個子串行(設為s1,s2,...sn),使得這個子串行滿足這樣的性質,s1演算法1(n^2):我們依次遍歷整個序列,每一次求出從第乙個數到當前這個數的最長上公升子串行,直至遍歷到最後乙個數字為止,然後再取dp陣列裡最大的那個即為整個序列的最長上公升子串行。我們用dp[i]來存放序列1-i的最長上公升子串行的長度,那麼dp[i]=max(dp[j])+1,(j∈[1, i-1]); 顯然dp[1]=1,我們從i=2開始遍歷後面的元素即可。
下面是模板:
//最長上公升子串行(n^2)模板
//入口引數:1.陣列名稱 2.陣列長度(注意從1號位置開始)
template
int lis(t a,int n)
return ans;
}演算法2(nlogn):維護乙個一維陣列c,並且這個陣列是動態擴充套件的,初始大小為1,c[i]表示最長上公升子串行長度是i的所有子串中末尾最小的那個數,根據這個數字,我們可以比較知道
,只要當前考察的這個數比c[i]大,那麼當前這個數一定能通過c[i]構成乙個長度為i+1的上公升子串行。當然我們希望在c陣列中找乙個盡量靠後的數字,這樣我們得到的上公升子串的長度最長,查詢的時候使用二分搜尋,這樣時間複雜度便下降了。
模板如下:
//最長上公升子串行nlogn模板
//入口引數:陣列名+陣列長度,型別不限,結構體型別可以通過過載運算子實現
//陣列下標從1號開始。
/**//begin_template_by_abilitytao_acm
template
int bsearch(t c,int n,t a)
}template
int lis(t a, int n)
return size;
}/**//end_template_by_abilitytao_acm
下面是pku上有關lis的題
pku 2533 ——longest ordered subsequence 裸lis,沒什麼可說的
#include
using namespace std;
int a[2000];
template
int lis(t a,int n)
return ans;
}int main ()
printf("%d\n" ,lis(a,n));
return 0;
}pku 1631——bridging signals 這題用n^2演算法要超時,必須使用nlogn的演算法
#include
#include
using namespace std;
const int n = 40000;
int a[n];
//最長上公升子串行nlogn模板
//入口引數:陣列名+陣列長度,型別不限,結構體型別可以通過過載運算子實現
//陣列下標從1號開始。
/**//begin_template_by_abilitytao_acm
template
int bsearch(t c,int n,t a)
}template
int lis(t a, int n)
return size;
}/**//end_template_by_abilitytao_acm
int main()
return 0;
}pku 1887——testing the catcher 最長不公升子串行,再次紀念下第一道動歸題
posted by abilitytao at 2008-09-25 00:50:48 on problem 1887
#include
#include
#include
#include
using namespace std;
int num[10000];
int dp[10000];
int main()
len=i-1;
dp[len]=1;
for(i=len-1;i>=0;i--)
printf("test #%d:\n maximum possible interceptions: %d\n\n",flag,finalmax);
flag++;
}return 0;
}pku 1609 tiling up blocks 二維最長不下降子串行
#include
#include
using namespace std;
#define max 100001
int dp[max];
struct node
l[max];
int cmp(const void *a,const void *b)
int main()
for(i=1;i<=n;i++)
qsort(l+1,n,sizeof(l[1]),cmp);
dp[1]=1;
int temp;
for(i=2;i<=n;i++)
dp[i]=temp+1;
if(dp[i]>maxnum)
maxnum=dp[i];
}printf("%d\n",maxnum);
}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 等等...
最長上公升子串行
最長上公升子串行問題 給出乙個由n個數組成的序列x 1.n 找出它的最長單調上公升子串行。即求最大的m和a1,a2 am,使得a1動態規劃求解思路分析 o n 2 經典的o n 2 的動態規劃演算法,設a i 表示序列中的第i個數,f i 表示從1到i這一段中以i結尾的最長上公升子串行的長度,初始時...
最長上公升子串行
時間限制 300ms 記憶體限制 1000k 提交次數 255 通過次數 118 題型 程式設計題 語言 無限制 description a numeric sequence ofai is ordered if a1 a2 an.let the subsequence of the given n...