可以发现每次都对后缀+1是不会劣的。考虑dp:设f[i][j]为前i个数一共+1了j次时包含第i个数的LIS长度。则f[i][j]=max(f[i][j-1],f[k][l]+1) (k<i,l<=j,a[i]+j>=a[k]+l)。容易发现这里是二维偏序,相当于查询(j,a[i]+j)左下部分的最大值,二维树状数组暴力维护,复杂度O(nklogklogv)。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 10010
#define M 510
#define V 5010
int n,m,a[N],f[N][M];
int tree[M][V+M];
void ins(int x,int y,int k)
{
for (;x<=m+;x+=x&-x)
for (int i=y;i<=;i+=i&-i)
tree[x][i]=max(tree[x][i],k);
}
int query(int x,int y)
{
int s=;
for (;x;x-=x&-x)
for (int i=y;i;i-=i&-i)
s=max(s,tree[x][i]);
return s;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj3594.in","r",stdin);
freopen("bzoj3594.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),m=read();
int t=;
for (int i=;i<=n;i++) a[i]=read();
for (int i=;i<=n;i++)
{
for (int j=;j<=m;j++)
{
if (j) f[i][j]=f[i][j-];
f[i][j]=max(f[i][j],query(j+,a[i]+j)+);
}
for (int j=;j<=m;j++)
ins(j+,a[i]+j,f[i][j]);
}
for (int i=;i<=n;i++) f[][m]=max(f[][m],f[i][m]);
cout<<f[][m];
return ;
}

  虽然看到题解清一色的都是二维BIT,仔细琢磨一下还是感觉自己原来的维护方法并没有假。容易发现f[i][j]>=f[i][j-1],那么k确定时l取值越大越好,所以两个限制至少有一个取等号。那么可以改为维护很多棵BIT,复杂度变为O(nk(logk+logv))。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 10010
#define M 510
#define V 5010
int n,m,a[N],f[N][M];
int tree1[M][V+M],tree2[V+M][M];
void ins1(int x,int k,int p){while (k<=) tree1[x][k]=max(tree1[x][k],p),k+=k&-k;}
void ins2(int x,int k,int p){while (k<=) tree2[x][k]=max(tree2[x][k],p),k+=k&-k;}
int query1(int x,int k){int s=;while (k) s=max(s,tree1[x][k]),k-=k&-k;return s;}
int query2(int x,int k){int s=;while (k) s=max(s,tree2[x][k]),k-=k&-k;return s;}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj3594.in","r",stdin);
freopen("bzoj3594.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),m=read();
int t=;
for (int i=;i<=n;i++) a[i]=read();
for (int i=;i<=n;i++)
{
for (int j=;j<=m;j++)
{
if (j) f[i][j]=f[i][j-];
f[i][j]=max(f[i][j],max(query1(j,a[i]+j),query2(a[i]+j,j+))+);
}
for (int j=;j<=m;j++)
ins1(j,a[i]+j,f[i][j]),ins2(a[i]+j,j+,f[i][j]);
}
for (int i=;i<=n;i++) f[][m]=max(f[][m],f[i][m]);
cout<<f[][m];
return ;
}

BZOJ3594 SCOI2014方伯伯的玉米田(动态规划+树状数组)的更多相关文章

  1. BZOJ3594 [Scoi2014]方伯伯的玉米田 【树状数组优化dp】

    题目链接 BZOJ3594 题解 dp难题总是想不出来,, 首先要观察到一个很重要的性质,就是每次拔高一定是拔一段后缀 因为如果单独只拔前段的话,后面与前面的高度差距大了,不优反劣 然后很显然可以设出 ...

  2. bzoj 3594: [Scoi2014]方伯伯的玉米田 dp树状数组优化

    3594: [Scoi2014]方伯伯的玉米田 Time Limit: 60 Sec  Memory Limit: 128 MBSubmit: 314  Solved: 132[Submit][Sta ...

  3. [SCOI2014]方伯伯的玉米田 题解(树状数组优化dp)

    Description 方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美. 这排玉米一共有N株,它们的高度参差不齐. 方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感 ...

  4. 洛谷P3287 [SCOI2014]方伯伯的玉米田(树状数组)

    传送门 首先要发现,每一次选择拔高的区间都必须包含最右边的端点 为什么呢?因为如果拔高了一段区间,那么这段区间对于它的左边是更优的,对它的右边会更劣,所以我们每一次选的区间都得包含最右边的端点 我们枚 ...

  5. BZOJ3594: [Scoi2014]方伯伯的玉米田【二维树状数组优化DP】

    Description 方伯伯在自己的农田边散步,他突然发现田里的一排玉米非常的不美. 这排玉米一共有N株,它们的高度参差不齐. 方伯伯认为单调不下降序列很美,所以他决定先把一些玉米拔高,再把破坏美感 ...

  6. bzoj3594: [Scoi2014]方伯伯的玉米田--树状数组优化DP

    题目大意:对于一个序列,可以k次选任意一个区间权值+1,求最长不下降子序列最长能为多少 其实我根本没想到可以用DP做 f[i][j]表示前i棵,操作j次,最长子序列长度 p[x][y]表示操作x次后, ...

  7. bzoj3594: [Scoi2014]方伯伯的玉米田

    dp新优化姿势... 首先,当我们拔高时,一定右端点是n最优.因为如果右端点是r,相当于降低了r之后玉米的高度.显然n更优. 那么可以dp.dp[i][j]表示前i个拔高j次的LIS.dp[i][j] ...

  8. 2019.03.28 bzoj3594: [Scoi2014]方伯伯的玉米田(二维bit优化dp)

    传送门 题意咕咕咕 思路:直接上二维bitbitbit优化dpdpdp即可. 代码: #include<bits/stdc++.h> #define N 10005 #define K 5 ...

  9. [BZOJ3594] [Scoi2014]方伯伯的玉米田 二维树状数组优化dp

    我们发现任何最优解都可以是所有拔高的右端点是n,然后如果我们确定了一段序列前缀的结尾和在此之前用过的拔高我们就可以直接取最大值了然后我们在这上面转移就可以了,然后最优解用二维树状数组维护就行了 #in ...

随机推荐

  1. [BZOJ1185][HNOI2007]最小矩形覆盖-[凸包+旋转卡壳]

    Description 传送门 Solution 感性理解一下,最小矩形一定是由一条边和凸包上的边重合的. 然后它就是模板题了..然而真的好难调,小于大于动不动就打错. Code #include&l ...

  2. 苏州Uber优步司机奖励政策(4月11日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  3. DSP28335做FFT傅里叶变换

    1. 看了一下例程,居然没有FFT的例程,难道这个DSP28335不能做FFT吗?对了C2000系列是有C2000 ware这个库的.方便很多,不过目前不确定在C5000上运行的FFT能直接迁移到DS ...

  4. 让系统识别特殊字符的密码(linux)

    mysql -h主机 -u用户 -p密码 当密码是! @ # 等特殊字符是,linux无法直接识别会报错 这种情况下可以参考以下两种方法: 1.-p后面不写密码,直接回车,再输入密码即可 2.用“\” ...

  5. docker基本的常用命令

  6. mac安装pkg 一直“正在验证” 卡着

    今天换了新mac, 但是之前wireshark(抓包工具) 不能用了 ,要安装Xquartz. 下载之后一直卡着, 网上找了半天没有解决方法. 最后我重启一下就好了... 重启一下. 2. 15款ma ...

  7. 袋鼠云研发手记 | 袋鼠云EasyManager的TypeScript重构纪要

    作为一家创新驱动的科技公司,袋鼠云每年研发投入达数千万,公司80%员工都是技术人员,袋鼠云产品家族包括企业级一站式数据中台PaaS数栈.交互式数据可视化大屏开发平台Easy[V]等产品也在迅速迭代.在 ...

  8. 常用JDBC数据库驱动包和类名

    MySQL数据库: 1)驱动包:https://mvnrepository.com/artifact/mysql/mysql-connector-java(下载路径) 2)驱动类名:com.mysql ...

  9. 阿里与ShopRunner达成协议 联手在国内推出服务

    阿里巴巴集团与美国在线零售商 ShopRunner 达成协议,将帮助后者在中国大陆销售商品和履行订单交付产品. ShopRunner 首席战略官菲奥娜·迪亚斯(Fiona Dias)周三接受媒体采访时 ...

  10. sshpass 指定密码远程 ssh 到服务器 或者 scp 发送文件到服务器

    在操作linux时,虽然可以对linux配置免秘钥登录,但是在配置免密码登录之前,是需要登录到其他节点主机的,这里提供一种类似ssh的方式,可以在命令后面加上相应的参数来设置你将要登录的远程主机的密码 ...