1109: [POI2007]堆积木Klo
1109: [POI2007]堆积木Klo
https://lydsy.com/JudgeOnline/problem.php?id=1109
分析:
首先是dp,f[i]表示到第i个的最优值,f[i]=f[j]+1,(j<i,a[j]<a[i],j-a[j]<i-a[i]),三维偏序,可以cdq+线段树转移。实际上由a[j]<a[i]和j-a[j]<i-a[i]可以推出j<i所以二维偏序,直接LIS。
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ; struct Node{
int x, c;
bool operator < (const Node &A) const {
return x == A.x ? c > A.c : x < A.x;
}
}A[N];
int f[N]; int main() {
int n = read(), cnt = ;
for (int i = ; i <= n; ++i) {
int x = read();
if (i - x >= )
A[++cnt].x = x, A[cnt].c = i - x;
}
if (cnt == ) {
cout << ; return ;
}
int len = ;
sort(A + , A + cnt + );
f[] = A[].c;
for (int i = ; i <= cnt; ++i) {
if (A[i].x != A[i - ].x && A[i].c >= f[len]) f[++len] = A[i].c;
else {
int p = upper_bound(f + , f + len + , A[i].c) - f;
f[p] = A[i].c;
}
}
cout << len;
return ;
}
LIS
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ; struct Node{
int id, x, c;
bool operator < (const Node &A) const {
return c == A.c ? x < A.x : c < A.c;
}
}A[N], B[N];
int f[N], mx; #define Root 1, mx, 1
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
struct SegmentTree{
int mx[N << ];
SegmentTree() { for (int i = ; i <= ; ++i) mx[i] = -1e9; }
void update(int l,int r,int rt,int p,int v) {
if (l == r) { mx[rt] = v; return ; }
int mid = (l + r) >> ;
if (p <= mid) update(lson, p, v);
else update(rson, p, v);
mx[rt] = max(mx[rt << ], mx[rt << | ]);
}
int query(int l,int r,int rt,int p) {
if (p < ) return -1e9;
if (r <= p) return mx[rt];
int mid = (l + r) >> ;
if (p <= mid) return query(lson, p);
else return max(mx[rt << ], query(rson, p));
}
}T; void cdq(int l,int r) {
if (l >= r) return ;
int mid = (l + r) >> ;
cdq(l, mid);
for (int i = mid + ; i <= r; ++i) B[i] = A[i];
sort(B + mid + , B + r + );
for (int p = l, j = mid + ; j <= r; ++j) {
if (f[B[j].id] == -1e9) continue;
while (p <= mid && A[p].c <= B[j].c) T.update(Root, A[p].x, f[A[p].id]), p ++;
f[B[j].id] = max(f[B[j].id], T.query(Root, B[j].x - ) + );
}
for (int i = l; i <= mid; ++i) T.update(Root, A[i].x, ); // B[i].x!!!
cdq(mid + , r);
sort(A + l, A + r + );
} int main() {
int n = read();
for (int i = ; i <= n; ++i) {
A[i].x = read(), A[i].id = i, A[i].c = i - A[i].x;
if (A[i].x <= i) f[i] = ;
else f[i] = -1e9;
mx = max(mx, A[i].x);
}
cdq(, n);
int ans = ;
for (int i = ; i <= n; ++i) ans = max(ans, f[i]);
cout << ans;
return ;
}
CDQ
1109: [POI2007]堆积木Klo的更多相关文章
- BZOJ 1109: [POI2007]堆积木Klo
1109: [POI2007]堆积木Klo Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 948 Solved: 341[Submit][Statu ...
- BZOJ 1109 [POI2007]堆积木Klo(树状数组)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1109 [题目大意] Mary在她的生日礼物中有一些积木.那些积木都是相同大小的立方体. ...
- bzoj 1109 [POI2007]堆积木Klo(LIS)
[题意] n个数的序列,删除一个数后序列左移,求最后满足i==a[i]的最大个数. [思路] 设最终得到a[i]==i的序列为s,则s应满足: i<j,a[i]<a[j],i-a[i]&l ...
- 【BZOJ】1109: [POI2007]堆积木Klo
题意 \(n(1 \le n \le 100000)\)个数放在一排,可以一走一些数(后面的数向前移),要求最大化\(a_i=i\)的数目. 分析 分析容易得到一个dp方程. 题解 \(d(i)\)表 ...
- BZOJ 1109 POI2007 堆积木Klo LIS
题目大意:给定一个序列,能够多次将某个位置的数删掉并将后面全部数向左串一位,要求操作后a[i]=i的数最多 首先我们如果最后a[i]=i的数的序列为S 那么S满足随着i递增,a[i]递增(相对位置不变 ...
- BZOJ.1109.[POI2007]堆积木Klo(DP LIS)
BZOJ 二维\(DP\)显然.尝试换成一维,令\(f[i]\)表示,强制把\(i\)放到\(a_i\)位置去,现在能匹配的最多数目. 那么\(f[i]=\max\{f[j]\}+1\),其中\(j& ...
- 【BZOJ1109】[POI2007]堆积木Klo 二维偏序
[BZOJ1109][POI2007]堆积木Klo Description Mary在她的生日礼物中有一些积木.那些积木都是相同大小的立方体.每个积木上面都有一个数.Mary用他的所有积木垒了一个高塔 ...
- 【bzoj1109】[POI2007]堆积木Klo 动态规划+树状数组
题目描述 Mary在她的生日礼物中有一些积木.那些积木都是相同大小的立方体.每个积木上面都有一个数.Mary用他的所有积木垒了一个高塔.妈妈告诉Mary游戏的目的是建一个塔,使得最多的积木在正确的位置 ...
- BZOJ1109 : [POI2007]堆积木Klo
f[i]表示第i个在自己位置上的最大值 则f[i]=max(f[j])+1 其中 j<i a[j]<a[i] a[i]-a[j]<=i-j -> j-a[j]<=i-a[ ...
随机推荐
- angularJs购物金额实例操作
<!DOCTYPE HTML> <html ng-app> <head> <meta http-equiv="Content-Type" ...
- Spring+ehcache+redis两级缓存
问题描述 场景:我们的应用系统是分布式集群的,可横向扩展的.应用中某个接口操作满足以下一个或多个条件: 1. 接口运行复杂代价大, 2. 接口返回数据量大, 3. 接口的数据基本不会更改, 4. 接口 ...
- 【[NOI2010]超级钢琴】
我竟然又在写主席树 现在可是九月啦,我却还在写这种noip不可能考的算法 我觉得我真的要凉 题意很明确,就是给你一个序列,让从中选择\(k\)段连续的序列,长度必须大于等于\(L\)小于等于\(R\) ...
- EF直接的一對多多對多多對一的關係----也即是鏈錶查詢
基于EF4.1 code first 简单的CRUD 园子中已经有很多了 ~~ 真不想再写这个了 可是为了做一个完整的小demo 从开始 到后面的一些简单重构 还是决定认真把这个写出来 争取写些别人 ...
- QTP基本方法3-----截屏
1.桌面截屏 Desktop.captureBitMap path[,bolean] path:保存路径,可选择绝对路径或相对路径 相对路径是保存在脚本保存的目录下编号最大的res目录下. bole ...
- 利用JDK自带工具keyTool生成安全证书
前言:说一下最近做的工作,主要利用iText给网页中生成好的html报表转化为pdf格式的文件,并且在其中加入水印,数字签名等等,这部分主要介绍安全证书的目的就是为了做数字签名部分用的. 下面利用jd ...
- PAT——1057. 数零壹
给定一串长度不超过105的字符串,本题要求你将其中所有英文字母的序号(字母a-z对应序号1-26,不分大小写)相加,得到整数N,然后再分析一下N的二进制表示中有多少0.多少1.例如给定字符串“PAT ...
- PAT——1040. 有几个PAT
字符串APPAPT中包含了两个单词“PAT”,其中第一个PAT是第2位(P),第4位(A),第6位(T):第二个PAT是第3位(P),第4位(A),第6位(T). 现给定字符串,问一共可以形成多少个P ...
- python codecs模块 ---处理数据写入文件时会有编码不统一的问题
我们用open方法打开文件有时候会有一些问题,因为open打开文件只能写入str类型,而不会管字符串是什么编码方式. 示例: >>> fr = open('test.txt','a' ...
- iOS开发UI篇 -- UISearchBar 属性、方法详解及应用(自定义搜索框样式)
很多APP都会涉及到搜索框,苹果也为我们提供了默认的搜索框UISearchBar.但实际项目中我们通常需要更改系统默认搜索框的样式.为了实现这一目标,我们需要先搞懂 UISearchBar 的属性及方 ...