设 \(f[i][j]\) 为第 \(i\) 天在第 \(j\) 个位置放置的最大值,设 \(s[i][j]\) 是第 \(i\) 行的前缀和,则

\[\begin{align}
f[i][j] & =s[i+1][j+k-1]-s[i+1][j-1]+ \\ \max_l &
\begin{cases}
f[i-1][l]+s[i][j+k-1]-s[i][j-1] & (1 \leq l \leq j-k) \\
f[i-1][l]+s[i][j+k-1]-s[i][l+k-1] & (j-k+1 \leq l \leq j) \\
f[i-1][l]+s[i][l-1]-s[i][j-1] & (j+1 \leq l \leq j+k-1) \\
f[i-1][l]+s[i][j+k-1]-s[i][j-1] & (j+k \leq l \leq m-k+1)
\end{cases}
\end{align}
\]

如果暴力转移,则复杂度 \(O(nm^2 )\)

如果 \(k\) 很小,那么对中间两种情况暴力转移,旁边两种由于只有 \(f[i-1][l]\) 与 \(l\) 有关,可以预处理前后缀 \(\max\) 来解决,复杂度 \(O(nmk)\)

当 \(k\) 变大时,两侧的情况仍然暴力转移,中间的情况可以暴力用以 \(l\) 为下标的单调队列维护 \(f[i-1][l]-s[i][l+k-1]\) 和 \(f[i-1][l]+s[i][l-1]\)

(如果想偷懒也可以敲个线段树维护一下)

(发现单调队列优化DP不太熟练,准备要复习下)

#include <bits/stdc++.h>
using namespace std; #define int long long
const int N = 55, M = 20005; int a[N][M],s[N][M],f[N][M],n,m,k,q[M],qt[M],l,r; signed main() {
cin>>n>>m>>k;
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
cin>>a[i][j];
s[i][j]=s[i][j-1]+a[i][j];
}
}
for(int i=1;i<=m-k+1;i++)
f[1][i]=s[1][i+k-1]-s[1][i-1]+s[2][i+k-1]-s[2][i-1];
for(int i=2;i<=n;i++) {
for(int j=1;j<=m-k+1;j++)
q[j]=f[i-1][j];
for(int j=1;j<=m-k+1;j++)
q[j]=max(q[j],q[j-1]);
for(int j=k;j<=m-k+1;j++)
f[i][j]=max(f[i][j],q[j-k]+s[i][j+k-1]-s[i][j-1]);
for(int j=m-k+1;j;j--)
q[j]=f[i-1][j];
for(int j=m-k+1;j;j--)
q[j]=max(q[j],q[j+1]);
for(int j=1;j<=m-k+1;j++)
f[i][j]=max(f[i][j],q[j+k]+s[i][j+k-1]-s[i][j-1]);
l=1;r=0;
for(int j=1;j<=m-k+1;j++) q[j]=-1e9;
for(int j=1;j<=m-k+1;j++) {
while(l<=r && q[r]<f[i-1][j]-s[i][j+k-1]) --r;
++r;
q[r]=f[i-1][j]-s[i][j+k-1];
qt[r]=j;
while(l<=r && qt[l]<j-k+1) ++l;
if(l<=r) f[i][j]=max(f[i][j],q[l]+s[i][j+k-1]);
}
l=1;r=0;
for(int j=1;j<=m-k+1;j++) q[j]=-1e9;
for(int j=m-k+1;j;--j) {
while(l<=r && q[r]<f[i-1][j]+s[i][j-1]) --r;
++r;
q[r]=f[i-1][j]+s[i][j-1];
qt[r]=j;
while(l<=r && qt[l]>j+k-1) ++l;
if(l<=r) f[i][j]=max(f[i][j],q[l]-s[i][j-1]);
}
for(int j=1;j<=m-k+1;j++) f[i][j]+=s[i+1][j+k-1]-s[i+1][j-1];
}
int ans=0;
/*for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) cout<<f[i][j]<<"\t";
cout<<endl;
}*/
for(int i=1;i<=m;i++) ans=max(f[n][i],ans);
cout<<ans;
}

[CF1304F] Animal Observation - dp,单调队列的更多相关文章

  1. Codeforces 1304F1/F2 Animal Observation(单调队列优化 dp)

    easy 题目链接 & hard 题目链接 给出一张 \(n \times m\) 的矩阵,每个格子上面有一个数,你要在每行选出一个点 \((i,t)\),并覆盖左上角为 \((i,t)\), ...

  2. [poj3017] Cut the Sequence (DP + 单调队列优化 + 平衡树优化)

    DP + 单调队列优化 + 平衡树 好题 Description Given an integer sequence { an } of length N, you are to cut the se ...

  3. DP+单调队列 codevs 1748 瑰丽华尔兹(还不是很懂具体的代码实现)

    codevs 1748 瑰丽华尔兹 2005年NOI全国竞赛  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 大师 Master 题解       题目描述 Descripti ...

  4. 习题:烽火传递(DP+单调队列)

    烽火传递[题目描述]烽火台又称烽燧,是重要的防御设施,一般建在险要处或交通要道上.一旦有敌情发生,白天燃烧柴草,通过浓烟表达信息:夜晚燃烧干柴,以火光传递军情.在某两座城市之间有n个烽火台,每个烽火台 ...

  5. (noip模拟二十一)【BZOJ2500】幸福的道路-树形DP+单调队列

    Description 小T与小L终于决定走在一起,他们不想浪费在一起的每一分每一秒,所以他们决定每天早上一同晨练来享受在一起的时光. 他们画出了晨练路线的草图,眼尖的小T发现可以用树来描绘这个草图. ...

  6. 3622 假期(DP+单调队列优化)

    3622 假期 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 黄金 Gold 题目描述 Description 经过几个月辛勤的工作,FJ决定让奶牛放假.假期可以在1-N天内任意选择 ...

  7. bzoj2500: 幸福的道路(树形dp+单调队列)

    好题.. 先找出每个节点的树上最长路 由树形DP完成 节点x,设其最长路的子节点为y 对于y的最长路,有向上和向下两种情况: down:y向子节点的最长路g[y][0] up:x的次长路的g[x][1 ...

  8. URAL 1427. SMS(DP+单调队列)

    题目链接 我用的比较传统的办法...单调队列优化了一下,写的有点搓,不管怎样过了...两个单调队列,存两个东西,预处理一个标记数组存... #include <iostream> #inc ...

  9. [USACO2004][poj2373]Dividing the Path(DP+单调队列)

    http://poj.org/problem?id=2373 题意:一条直线分割成N(<=25000)块田,有一群奶牛会在其固定区域吃草,每1把雨伞可以遮住向左右延伸各A到B的区域,一只奶牛吃草 ...

随机推荐

  1. Linux系统开机显示BusyBox v1.22.1 built-in shell(ash) 解决方法

    BusyBox 是一个集成了三百多个最常用Linux命令和工具的软件.BusyBox 包含了一些简单的工具,例如ls.cat和echo等等,还包含了一些更大.更复杂的工具,例grep.find.mou ...

  2. #《H.264和MPEG-4视频压缩》# 一. 色彩空间

    多数的数字视频应用需要播放彩色的视频信号,所以需要捕获和重现颜色信息.一幅黑白图像的每一个采样点只需要一个像素表示明暗或亮度,而在彩色图像中至少需要3个像素来表示每个像素的色彩.表示亮度和色彩的不同方 ...

  3. Jetty配置虚拟目录,实现把web项目发布到自定义目录,指定指定上下文访问;jetty编码修改

    2019-12-31     17:28:38 一般只需要把Java站点文件夹或*.war文件拷贝到Web Server的webapps文件夹下,即可启动运行该站点,但更多时候,我们并不想拷贝站点,而 ...

  4. 教你如何理解JAVA的I/O类库

    花括号MC(huakuohao-mc):关注JAVA基础编程及大数据,注重经验分享及个人成长. Java 的 I/O 流,说简单也简单,说复杂也复杂.复杂是因为进行一次常规的文件 I/O 操作通常要用 ...

  5. 接口文档word版

    一. 分类中某某某接口 接口说明: 请求URL: http://120.26.212.11:8199/xhcms/catalogFirst 请求参数说明: 参数名 必选 类型 参数说明 返回: {&q ...

  6. 初始socket编程

    服务端语法 import socket # 导入套接字模块# 生成一个socket对象进行网络编程操作server = socket.socket(family=socket.AF_INET, typ ...

  7. Java中Thread方法启动线程

    public class ThreadTest extends Thread {  private int count = 10; @Override public void run() { //重写 ...

  8. 制作MySQL RPM安装包Spec

    适用环境: 数据库版本:MySQL 操作系统:CentOS 7 制作思路: 将数据库初始化和配置工作放到安装脚本中方便定制: 1.打包MySQL应用目录 2.不自动生成配置文件 3.不自动生成数据目录 ...

  9. 剑指offer-面试题53_1-在排序数组中查找数字-二分查找

    /* 题目: 统计一个数字在排序数组中出现的次数. */ /* 思路: 1.从前往后遍历,时间复杂度O(n). 2.二分查找到目标数字target,向前向后遍历,时间复杂度O(n). 3.利用二分法, ...

  10. phyon tensorflow 安装(centos)

    1.phyon27 安装 1.1 下载 wget https://www.python.org/ftp/python/2.7.14/Python-2.7.14.tgz 1.2  解压 tar -zxv ...