您的位置:首页 > 其它

poj 1631 || hdu 1950 Bridging signals(动态规划:LIS)

2014-08-28 17:18 211 查看
题目其实就是让你求LIS

但是因为题目中说了p<=40000

如果用O(n*n)的算法,必然超时

所以需要优化

看了下O(n*logn)的算法

解释如下:

先说下O(n*n)的算法:

用dp[i]保存以a[i]结尾的LIS最长长度

则对于当前的a[i],我们需要找到满足a[j]<a[i](j<i)且最大的dp[j]

则dp[i] = max(dp[i], dp[j]+1);

而优化就在于查找过程

用a数组保存给出的数据

用b[i]保存所有LIS长度为i-1的末尾最小元素值

则每次在b数组中二分查找满足条件的下标tmp

令b[tmp+1] = a[i]即可

代码如下:

#include <cstdio>
#define MAXN 40010
using namespace std;

int a[MAXN], b[MAXN];

int bin(int l, int r, int val) {
int m;
while(l <= r) {
m = (l+r) >> 1;
if(b[m] > val)
r = m-1;
else l = m+1;
}
return r;
}

int main(void) {
int T, n, tmp;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i=0; i<n; ++i)
scanf("%d", &a[i]);

int ans = 0;
b[0] = a[0];
for(int i=1; i<n; ++i) {
tmp = bin(0, ans, a[i])+1;//tmp:以a[i]结尾的LIS长度-1
b[tmp] = a[i];
//printf("b[%d] = a[%d] = %d\n", tmp, i, a[i]);
if(tmp > ans)
ans = tmp;//当前最长LIS长度-1
}

printf("%d\n", ans+1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: