【DP】最长不下降子序列问题(二分)
2015-08-19 19:23
363 查看
Description
给你一个长度为n的整数序列,按从左往右的顺序选择尽量多的数字并且满足这些数字不下降。Thinking
朴素dp算法:F[i]表示到第i位为止的最长不下降子序列长度F[i]=max(F[j])+1 (j为1~(i-1)个数中小于a[i]的数)
时间复杂度:O(n2)
考虑维护一个队列g,用g[i]表示长度为i的最长不下降子序列结尾的最小值。根据g[i]的单调性,可以用二分查找的方法快速找到以当前数a[i]结尾的最长不下降子序列
Code
#include<cstdio> #include<cstring> #define FA(i,s,t) for(int i=s;i<=t;i++) #define FD(i,s,t) for(int i=s;i>=t;i--) using namespace std; int n; int num[10000]; int g[10000],f[10000]; void Insert(int x,int s,int t) //不使用递归的方法提高效率 { int left,right,mid; left=s; right=t; while(left<=right) { mid=(left+right)/2; if(g[mid]==x) { while(g[mid]==x) ++mid; g[mid]=x; return; } if(g[mid]>x) right=mid-1; if(g[mid]<x) { if(g[mid+1]>x) { g[mid+1]=x; return; } left=mid+1; } } } int main() { scanf("%d",&n); FA(i,1,n) { scanf("%d",&num[i]); } memset(g,0,sizeof(g)); int t=1; FA(i,1,n) { if(num[i]>=g[t-1]) { g[t]=num[i]; t++; } else { Insert(num[i],0,t); } } int ans=t-1; printf("%d\n",ans); return 0; }
相关文章推荐
- 基于Android中dp和px之间进行转换的实现代码
- Android中dip、dp、sp、pt和px的区别详解
- LFC1.0.0 版本发布
- Android px、dp、sp之间相互转换
- android中像素单位dp、px、pt、sp的比较
- Android对px和dip进行尺寸转换的方法
- Android根据分辨率进行单位转换-(dp,sp转像素px)
- android 尺寸 dp,sp,px,dip,pt详解
- DP问题各种模型的状态转移方程
- TYVJ1193 括号序列解题报告
- 对DP的一点感想
- TYVJ上一些DP的解题报告
- soj1005. Roll Playing Games
- 01背包问题
- LeetCode之Maximum Product Subarray
- DP Flow
- zoj3605 Find the Marble(三维dp)
- Word Break I,II, Triangle,Palindrome Partitioning 动态规划 DP
- Unique Paths I,II, Minimum Path Sum
- Gas Station