hdu4521 dp+树状数组

来源:互联网 发布:淘宝页头150px图片 编辑:程序博客网 时间:2024/06/06 00:06

很容易想到是dp,类似于最长公共子序列n^2的求法,但是n^2的做法肯定会TLE的,就要想着优化。

很容易想到线段树,其实树状数组也是可以做的。做dp的时候才用顺推的方法,逐步去更新。

有一个坑点是d可能为0,然后就会TLE了,常见的处理方法,我们把所有的数都加一就好了。

//  Created by Chenhongwei in 2015.//  Copyright (c) 2015 Chenhongwei. All rights reserved.#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <climits>#include <queue>#include <cmath>#include <map>#include <set>#include <stack>#include <vector>#include <sstream>#include <algorithm>using namespace std;const int inf=1e9;const int maxn=1e5+1000;typedef long long ll;typedef unsigned long long ull;int a[maxn],c[maxn];int dp[maxn];int n,d,L;int lowbit(int x){return x&(-x);}void update(int x,int v){while(x<=L+10){c[x]=max(c[x],v);x+=lowbit(x);}}int maxv(int x){int ret=0;while(x>0){ret=max(ret,c[x]);x-=lowbit(x);}return ret;}int main(){//ios::sync_with_stdio(false);// freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);while(scanf("%d%d",&n,&d)!=EOF){memset(c,0,sizeof c);memset(dp,0,sizeof dp);int ans=1;L=0;for(int i=1;i<=n;i++){scanf("%d",&a[i]);a[i]+=1;L=max(L,a[i]);}for(int i=1;i<=n;i++){dp[i]=max(dp[i],1);update(a[i],dp[i]);if(i+d+1<=n){dp[i+d+1]=max(maxv(a[i+d+1]-1)+1,dp[i+d+1]);ans=max(ans,dp[i+d+1]);}}cout<<ans<<endl;}return 0;}




0 0