hdu 4521 腾讯 小明序列
2014-02-23 21:15
190 查看
这题有两种算法,第一种是线段树,第二种是最长上升子序列(LIS)的变种。
先记下LIS的:
普通的LIS的O(nlogn)的算法是:维护一个栈,每次读到的元素和栈顶元素比较,如果大则入栈,否则二分查找第一个大于它的数,并替换(潜力增大),序列长度就是栈的长度。本题限定是间隔为d,解决办法是延迟入栈。避免中间一段的dp[i]受到影响。
线段树的做法基本相似,用len[val]表示小于值val结尾的最大长度,延迟更新。注意A[i]取值范围可能是0
先记下LIS的:
普通的LIS的O(nlogn)的算法是:维护一个栈,每次读到的元素和栈顶元素比较,如果大则入栈,否则二分查找第一个大于它的数,并替换(潜力增大),序列长度就是栈的长度。本题限定是间隔为d,解决办法是延迟入栈。避免中间一段的dp[i]受到影响。
#include<cstdio> #include<algorithm> #include<iostream> using namespace std; const int N=100005; int data ,stack ,dp ; int main(){ int n,d;//间隔d while(cin>>n>>d){ for(int i=1;i<=n;++i) cin>>data[i]; memset(dp,0,sizeof(dp)); memset(stack,0x3f,sizeof stack); stack[0]=-1; for(int i=1;i<=n;++i){ int k=lower_bound(stack,stack+n,data[i])-stack; dp[i]=k;//栈顶下标 即 第i个元素结尾的长度 if(i-d > 0)//延迟入栈 stack[dp[i-d]]=min(stack[dp[i-d]],data[i-d]); } int ans=0; for(int i=1;i<=n;++i) ans=max(ans,dp[i]); cout<<ans<<endl; } return 0; }
线段树的做法基本相似,用len[val]表示小于值val结尾的最大长度,延迟更新。注意A[i]取值范围可能是0
#include<cstdio> #include<algorithm> #include<iostream> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 const int N=110000; int A ,len[N*4],dp ; inline int max(int a,int b){ return a>b?a:b; } void push_up(int rt){ len[rt]=max(len[rt*2],len[rt*2+1]); } void update(int p,int c,int l,int r,int rt){//单点更新 值p结尾的最大长度为c if(l==r){ len[rt]=max(len[rt],c); return; } int m=(l+r)>>1; if(p<=m) update(p,c,lson); if(p>m) update(p,c,rson); push_up(rt); } int query(int a,int b,int l,int r,int rt){//查询 [0,A[i]-1]结尾的最大长度 if(a<=l&&b>=r) return len[rt]; int rst=0,m=(l+r)>>1; if(a<=m) rst=max(rst,query(a,b,lson)); if(b>m) rst=max(rst,query(a,b,rson)); return rst; } int main(){ int n,d; while(~scanf("%d %d",&n,&d)){ int ans=0; for(int i=1;i<=n;i++) scanf("%d",&A[i]); memset(len,0,sizeof len); for(int i=1;i<=n;i++){//由于A[i]可能=0,所以+1 dp[i]=query(1,A[i]+1,1,N,1)+1; if(i>d) update(A[i-d]+2,dp[i-d],1,N,1); if(dp[i]>ans) ans=dp[i]; } printf("%d\n",ans); } return 0; }
相关文章推荐
- HDU 4521 2013腾讯编程马拉松初赛第四场 小明系列问题——小明序列(dp思想+线段树优化)
- 【HDU】4521 小明系列问题——小明序列 线段树+DP
- HDU 4521(小明系列问题——小明序列)
- hdu 4521 小明系列问题——小明序列(求间距大于d的最长上升序列)
- hdu 4521 小明系列问题——小明序列(线段树)
- HDU 4521 小明系列问题——小明序列 (LIS加强版)
- hdu 4521 小明序列
- HDU 4521 小明系列问题——小明序列
- HDU 4521 小明系列问题——小明序列(LIS变形)
- HDU - 4521 小明系列问题――小明序列 (LIS&DP)好题
- HDU 4521 小明系列问题——小明序列 DP – LIS加强版 #by Plato
- HDU 4521 小明系列问题——小明序列 LIS+动态规划
- HDU 4521 小明系列问题--小明序列(加强版LIS+线段树单点更新)
- HDU 4521小明序列(变形的LIS)
- HDU 4521 小明系列问题——小明序列【dp+线段树优化||最长递增序列】
- HDU:4521 小明系列问题——小明序列(LIS-n*logn解法变形+思维+技巧)
- 树线段线段树(端点更新) hdu-4521 小明系列问题——小明序列
- 【HDU 杭电 4521 小明系列问题——小明序列】
- HDU-4521 小明序列 线段树+DP
- hdu 4521 小明系列问题——小明序列(lis)