ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【洛谷6564】[POI2007] 堆积木KLO(树状数组优化DP)

2021-06-11 19:34:28  阅读:227  来源: 互联网

标签:le10 洛谷 树状 int 6564 POI2007 数组 Reg define


点此看题面

  • 给定一个长度为\(n\)的序列,你可以删去其中若干元素,要求最大化\(\sum_{i=1}^{n'}[a_i=i]\)。
  • \(n\le10^5,a_i\le10^6\)

树状数组优化\(DP\)

发现每个位置\(i\)只有被弄到第\(a_i\)个位置才能产生贡献,也就是说需要满足在前\(i-1\)个元素中删去了恰好\(i-a_i\)个。

设\(f_j\)表示把原序列中的位置\(j\)弄到了第\(a_j\)个位置上能满足条件的最大个数,考虑\(j\)能转移到\(i\)的条件:

\[\begin{cases} j<i,\\ a_j<a_i,\\ j-a_j\le i-a_i \end{cases} \]

发现满足了后两个条件一定能满足第一个,因此这其实是个二维偏序。

以\(a_i\)为下标开一个树状数组,然后按照\(i-a_i\)从小到大枚举转移即可。

代码:\(O(nlogn)\)

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define Con const
#define CI Con int&
#define I inline
#define W while
#define N 100000
#define V 1000000
using namespace std;
int n;vector<int> p[N+5];struct TreeArray
{
	int a[V+5];I void U(RI x,CI v) {W(x<=V&&a[x]<v) a[x]=v,x+=x&-x;}//单点取max
	I int Q(RI x,RI t=0) {W(x) t=max(t,a[x]),x-=x&-x;return t;}//前缀求最大值
}T;
int main()
{
	RI i,x;for(scanf("%d",&n),i=1;i<=n;++i) scanf("%d",&x),x<=i&&(p[i-x].push_back(x),0);//对于i-a[i]开桶
	vector<int>::iterator it;for(i=0;i<=V;++i) for(it=p[i].begin();it!=p[i].end();++it) T.U(*it,T.Q(*it-1)+1);//树状数组优化DP
	return printf("%d\n",T.Q(V)),0;
}

标签:le10,洛谷,树状,int,6564,POI2007,数组,Reg,define
来源: https://www.cnblogs.com/chenxiaoran666/p/Luogu6564.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有