【DP】#1109. [POI2007]堆积木Klo
https://darkbzoj.cc/problem/1109
分析
考虑状态表示原来在位置 的数有贡献(也就是说在结束操作后它的位置 满足 )的最大值为 。
那么我们有转移方程 ,其中 。
考虑优化转移:
也就是 。
可以发现 同时满足的时候第一个约束也必然满足,所以只需要考虑这两个约束。
因为 有等号,为了消除等号的影响,考虑根据 为第一关键字,下标为第二关键字进行排序。
排序后使用树状数组维护 的贡献即可。
#include<bits/stdc++.h>
using namespace std;
#define debug(x) cerr << #x << ": " << (x) << endl
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define dwn(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define x first
#define y second
using pii = pair<int, int>;
using ll = long long;
inline void read(int &x){
int s=0; x=1;
char ch=getchar();
while(ch<'0' || ch>'9') {if(ch=='-')x=-1;ch=getchar();}
while(ch>='0' && ch<='9') s=(s<<3)+(s<<1)+ch-'0',ch=getchar();
x*=s;
}
const int N=1e6+5;
int n;
struct Node{
int id, w;
bool operator < (const Node &o)const{
return id-w==o.id-o.w? id<o.id: id-w<o.id-o.w;
}
}w[N];
int tr[N];
int lowbit(int x){
return x&-x;
}
void upd(int x, int k){
for(; x<N; x+=lowbit(x)) tr[x]=max(tr[x], k);
}
int query(int x){
int res=0;
for(; x; x-=lowbit(x)) res=max(res, tr[x]);
return res;
}
signed main(){
cin>>n;
rep(i,1,n){
int x; read(x);
w[i]={i, x};
}
sort(w+1, w+1+n);
int res=0;
rep(i,1,n){
if(w[i].w>w[i].id) continue;
int mx=query(w[i].w-1);
res=max(res, mx+1);
upd(w[i].w, mx+1);
}
cout<<res<<endl;
return 0;
}
分类:
BZOJ
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】