【题解】Luogu P3287 [SCOI2014]方伯伯的玉米田
原题传送门
一眼就能看出来这是一道dp题
显而易见每次操作的右端点一定是n,每株玉米被拔高的次数随位置不下降
用f(i,j) 表示以第i 株玉米结尾它被拔高了j 次的最长序列长度。
\(f(i,j)=Max(f(p,q)+1)(0<=p<i,0<=q<j,a_p+q<a_i+j\)]
复杂度是\(O(n^2k^2)\)
显然过不了这题
用d(i, j) 表示到目前为止结尾玉米被拔高了i 次高度为j的最长序列长度。
我们需要不断更新这个表(当然不会下降) ,并查询二维前缀最大值。
这珂以用二维树状数组来维护
复杂度\(O(n \log n k \log k)\)
#include <bits/stdc++.h>
#define getchar nc
#define N 10005
#define K 505
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 int read()
{
register int x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}
inline void write(register int x)
{
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[20];register int tot=0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
inline int Max(register int a,register int b)
{
return a>b?a:b;
}
int n,k,tr[N][K],h[N],mx,ans=0;
inline int lb(register int x)
{
return x&(-x);
}
inline int query(register int x,register int y)
{
int res=0;
for(register int i=x;i;i-=lb(i))
for(register int j=y;j;j-=lb(j))
res=Max(tr[i][j],res);
return res;
}
inline void update(register int x,register int y,register int v)
{
for(register int i=x;i<=mx+k;i+=lb(i))
for(register int j=y;j<=k+1;j+=lb(j))
tr[i][j]=Max(tr[i][j],v);
}
int main()
{
n=read(),k=read();
for(register int i=1;i<=n;++i)
{
h[i]=read();
mx=Max(mx,h[i]);
}
for(register int i=1;i<=n;++i)
for(register int j=k;j>=0;--j)
{
int x=query(h[i]+j,j+1)+1;
ans=Max(ans,x);
update(h[i]+j,j+1,x);
}
write(ans);
return 0;
}
这已经能过这题了,但我们还珂以继续优化
我们珂以发现每次树状数组查询都有大量重复计算
所以珂以变成一维树状数组
#include <bits/stdc++.h>
#define getchar nc
#define N 10005
#define K 505
#define V 5005
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 int read()
{
register int x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}
inline void write(register int x)
{
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[20];register int tot=0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
inline int Max(register int a,register int b)
{
return a>b?a:b;
}
int n,k,ans,h[N],f[N][K];
struct BinaryIndexTree{
int maxx[V];
inline void update(register int pos,register int v)
{
++pos;
for(register int i=pos;i<=V-1;i+=i&(-i))
maxx[i]=Max(maxx[i],v);
}
inline int query(register int pos)
{
int res=0;
++pos;
for(register int i=pos;i;i-=i&(-i))
res=Max(res,maxx[i]);
return res;
}
}tr1[K];
struct BinaryIndexTree2{
int maxx[K];
inline void update(register int pos,register int v)
{
++pos;
for(register int i=pos;i<=k+1;i+=i&(-i))
maxx[i]=Max(maxx[i],v);
}
inline int query(register int pos)
{
int res=0;
++pos;
for(register int i=pos;i;i-=i&(-i))
res=Max(res,maxx[i]);
return res;
}
}tr2[K+V];
int main()
{
n=read(),k=read();
for(register int i=1;i<=n;++i)
h[i]=read();
for(register int i=1;i<=n;++i)
for(register int j=0;j<=k;++j)
{
int tmp1=tr1[j].query(h[i]),tmp2=tr2[h[i]+j].query(j);
f[i][j]=Max(tmp1,tmp2)+1,ans=Max(ans,f[i][j]);
tr1[j].update(h[i],f[i][j]),tr2[h[i]+j].update(j,f[i][j]);
}
write(ans);
return 0;
}
【题解】Luogu P3287 [SCOI2014]方伯伯的玉米田的更多相关文章
- 洛谷 P3287 - [SCOI2014]方伯伯的玉米田(BIT 优化 DP)
洛谷题面传送门 怎么题解区全是 2log 的做法/jk,这里提供一种 1log 并且代码更短(bushi)的做法. 首先考虑对于一个序列 \(a\) 怎样计算将其变成单调不降的最小代价.对于这类涉及区 ...
- 洛谷P3287 [SCOI2014]方伯伯的玉米田(树状数组)
传送门 首先要发现,每一次选择拔高的区间都必须包含最右边的端点 为什么呢?因为如果拔高了一段区间,那么这段区间对于它的左边是更优的,对它的右边会更劣,所以我们每一次选的区间都得包含最右边的端点 我们枚 ...
- P3287 [SCOI2014]方伯伯的玉米田
首先可以证明,一定存在一种最优解,每次选择的区间结尾都是 \(n\).因为如果某一个区间结尾不是 \(n\),将其替换成 \(n\) 仍然保持单调不下降.接着都按这个策略拔高玉米. 令 \(f_{i, ...
- bzoj 3594: [Scoi2014]方伯伯的玉米田 dp树状数组优化
3594: [Scoi2014]方伯伯的玉米田 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 314 Solved: 132[Submit][Sta ...
- bzoj 3594: [Scoi2014]方伯伯的玉米田
3594: [Scoi2014]方伯伯的玉米田 Time Limit: 60 Sec Memory Limit: 128 MB Submit: 1399 Solved: 627 [Submit][ ...
- [SCOI2014]方伯伯的玉米田 题解(树状数组优化dp)
Description 方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美. 这排玉米一共有N株,它们的高度参差不齐. 方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感 ...
- [SCOI2014]方伯伯的玉米田
Description 方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美. 这排玉米一共有N株,它们的高度参差不齐. 方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感 ...
- BZOJ3594: [Scoi2014]方伯伯的玉米田【二维树状数组优化DP】
Description 方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美. 这排玉米一共有N株,它们的高度参差不齐. 方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感 ...
- BZOJ3594 [Scoi2014]方伯伯的玉米田 【树状数组优化dp】
题目链接 BZOJ3594 题解 dp难题总是想不出来,, 首先要观察到一个很重要的性质,就是每次拔高一定是拔一段后缀 因为如果单独只拔前段的话,后面与前面的高度差距大了,不优反劣 然后很显然可以设出 ...
随机推荐
- Go 用JSON加载表格数据
支持热重载reload,但会有一些问题,下面注释有写 package table import ( "runtime/debug" ) //IntArray int类型数组 typ ...
- javascript变量作用域 全局及局部
$("#inStartTime").datetimepicker({ format: 'yyyy-mm-dd hh:ii', autoclose: true, todayBtn: ...
- asp.net mvc 路由检测工具
初学mvc,路由搞不清楚,可以通过一款插件 查看匹配的路由. 工具名<RouteDebugger> 可以在nuget中查询RouteDebugger后,安装.或者在控制台进行安装: pm& ...
- HTTP状态码--含义
以下是HTTP状态码(HTTP Status Code)及其解释 1xx(临时响应) (继续) 请求者应当继续提出请求. 服务器返回此代码表示已收到请求的第一部分,正在等待其余部分. (切换协议) 请 ...
- Tcp/IP 的四层模型
维基:https://zh.wikipedia.org/wiki/TCP/IP%E5%8D%8F%E8%AE%AE%E6%97%8F 因特网协议组 LITA 因特网协议组 Link 网络接口层 以太 ...
- properties文件读取工具类
项目中防止硬编码,经常会将一些与业务相关的数据存在properties文件中,根据不同的key加载不同的数据,所以就会有读取properties文件的东西,这篇文章仅为了以后copy方便写的. 1.添 ...
- ELK之elasticsearch导致CPU居高不下系统慢解决办法
参考:http://zoufeng.net/2018/07/16/cpu-of-elasticsearch-high-search-slow/ elasticsearch主机CPU居高不下100%左右 ...
- asp.net mvc ef 性能监控调试工具 MiniProfiler
MiniProfiler是一款针对.NET, Ruby, Go and Node.js的性能分析的轻量级程序.可以对一个页面本身,及该页面通过直接引用.Ajax.Iframe形式访问的其它页面进行监控 ...
- 内购审核被拒-[environment-sandbox]
内购审核被拒-[environment-sandbox] 先把新创建的项目提交审核通过后再提交主包 注意,新增加的内购项目要截图告诉苹果
- Fiddler过滤
1.REGEX:\.(js|css|js|png|gif|\?.*|css\?.*)$ 2..css .js .gif .png .jpg .swf