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]即可
代码如下:
但是因为题目中说了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; }
相关文章推荐
- Poj 1631 && Hdu 1950 Bridging signals【LIS】
- POJ 1631 && HDU 1950 Bridging signals(LIS)
- HDU 1950 POJ 1631 Bridging signals【LIS,二分优化】
- HDU 1950 Bridging signals (DP动态规划 + 二分搜索 O(nlogn) )
- 100道动态规划——20 HDU 1257 最少拦截系统 LIS 啊!我为什么这个都没有想到!
- HDU 1950 Bridging signals ( DP动态规划 O(n^2) )
- POJ1631——Bridging signals(动态规划,最长上升子序列应用)
- POJ 1631 HDU 1950(最长上升子序列问题)
- poj 1887 Testing the CATCHER(动态规划:LIS)
- 动态规划 ② HDU - 1087 Super Jumping! Jumping! Jumping! (LIS 最大上升子序列)
- POJ 1631 / HDU 1950 / ZOJ 1986 / Northwestern Europe 2003 Bridging signals (DP&LIS)
- Alphacode (动态规划思想)POJ - 2033 HDU - 1508
- 动态规划 加最少字符使字符串变回文 POJ 1159 short水过!
- 动态规划----FatMouse’s Speed(HDU 1160)
- 动态规划 POJ 1037 A decorative fence
- HDU动态规划部分题目统计
- 动态规划复习-HDU2084
- 动态规划-hdu 2955
- HDU 1024动态规划问题
- 动态规划入门(四)DP 基本思想 具体实现 经典题目 POJ1160 POJ1037