[ DP ] [ POI2007 ] BZOJ1109
2018-01-25 19:05
357 查看
先考虑 O(n2)O(n2) 的DP:
令 fifi 为使 ii 满足条件时前 ii 个数的答案。可以得到转移方程:
fi=max{fj+1 | j<i,aj<ai,ai−aj≤i−j}fi=max{fj+1 | j<i,aj<ai,ai−aj≤i−j}
发现通过后 22 个条件可以推出第一个条件。那么按照 i−aii−ai 排序然后求一遍最长上升子序列就好了。
令 fifi 为使 ii 满足条件时前 ii 个数的答案。可以得到转移方程:
fi=max{fj+1 | j<i,aj<ai,ai−aj≤i−j}fi=max{fj+1 | j<i,aj<ai,ai−aj≤i−j}
发现通过后 22 个条件可以推出第一个条件。那么按照 i−aii−ai 排序然后求一遍最长上升子序列就好了。
#include<bits/stdc++.h> using namespace std; inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline void Read(int& x){ char c=nc(); for(;c<'0'||c>'9';c=nc()); for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc()); } #define fi first #define se second typedef pair<int,int> abcd; const int N=100010; int k,n,m,x; int c ,Ans; abcd a ; inline int Find(int x){ int l=1,r=n-1,Ans=0; while(l<=r){ int Mid=l+r>>1; if(c[Mid]<x)Ans=Mid,l=Mid+1;else r=Mid-1; } return Ans; } int main(){ Read(n); int cnt=0; for(int i=1;i<=n;i++){ Read(x); if(i>=x)a[++cnt]=abcd(i-x,x); } n=cnt; sort(a+1,a+n+1); memset(c,127,sizeof(c)); for(int i=1;i<=n;i++){ x=Find(a[i].se)+1; c[x]=min(c[x],a[i].se); Ans=max(Ans,x); } cout<<Ans<<endl; return 0; }
相关文章推荐
- 【bzoj1109】 [POI2007]堆积木Klo
- 【bzoj1109】[POI2007]堆积木Klo 动态规划+树状数组
- BZOJ_1097_[POI2007]旅游景点atr_状压DP
- BZOJ 1109: [POI2007]堆积木Klo LIS
- bzoj 1097: [POI2007]旅游景点atr(状压DP)
- BZOJ1109: [POI2007]堆积木Klo
- BZOJ 1097: [POI2007]旅游景点atr [DP 状压 最短路]
- 【BZOJ1097】[POI2007]旅游景点atr 最短路+状压DP
- BZOJ 1109 [POI2007]堆积木Klo(树状数组)
- bzoj1111[POI2007]四进制的天平Wag 高精度+dp
- 【BZOJ】1109: [POI2007]堆积木Klo
- BZOJ 1109: [POI2007]堆积木Klo 神分析, LIS, BIT, 二分
- bzoj 1109: [POI2007]堆积木Klo LIS
- BZOJ 1097: [POI2007]旅游景点atr( 最短路 + 状压dp )
- bzoj 1109: [POI2007]堆积木Klo(二维偏序)
- BZOJ 1109: [POI2007]堆积木Klo
- BZOJ 1109 [POI2007]堆积木Klo DP
- BZOJ 1111: [POI2007]四进制的天平Wag 进制拆分,DP求方案数
- BZOJ 1109: [POI2007]堆积木Klo
- BZOJ 1109 POI2007 堆积木Klo LIS