题意:给出n,和m表示有n天,m块区域,每块区域都有一定数论的动物数量,k表示可以在这一天中观察[x,max(x+k-1,m)]的区域内的动物,有俩台相机,一台只能在偶数天用,另一台则是在奇数天用,每用一次就得在那个区域内待俩天,相邻的要是有重复的区域,该区域内的动物数只计数一次,问最多有可能的动物数目是多少

分析:因为n<=50,m<=20000,所以我们考虑一下dp[n][m],dp[i][j]表示:在第 i 天选择[j,j+k-1]区域拍摄的最大拍摄量。

   因为是连续拍摄俩天,所以我们可以想象一个块,这个块的大小是:2*k(2为连续拍摄俩天,k为连续的区域),然后第 i 天转移的过程就是这个块滑块的过程,下面考虑第 i 天;

   因为会涉及重复的问题,所以我们不妨直接把这个块全部算成都有效的块,然后这个块要和 (前一天的dp (减去这个块对这个前一天的dp)的影响) 相加才为选择这个区域来拍摄的最优值;

   接下来的dp就相当于这个块在第 i 天的dp数组上进行“滑块”,假设当前这个块(左上角为dp[i][j],dp[i+1][j+k-1])向右 “滑” ,那么就考虑加入[j+k]区域的动物对dp[i-1][]的影响和去掉 [j] 区域对dp[i-1][]的影响;

   这个影响靠线段树的区间加,区间最值来维护,详细可以看代码注释

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define lson root<<1,l,midd
#define rson root<<1|1,midd+1,r
const int M=2e4+;
const int N=;
int sum[N][M],a[N][M],dp[N][M];
struct node{
int lazy,val;
}tr[M<<];
void build(int root,int l,int r){
if(l==r){
tr[root].lazy=tr[root].val=;
return ;
}
int midd=(l+r)>>;
build(lson);
build(rson);
}
void pushdown(int root){
int x=tr[root].lazy;
tr[root<<].lazy+=x;
tr[root<<|].lazy+=x;
tr[root<<].val+=x;
tr[root<<|].val+=x;
tr[root].lazy=;
}
void up(int root){
tr[root].val=max(tr[root<<].val,tr[root<<|].val);
}
void update(int L,int R,int c,int root,int l,int r){
if(L<=l&&r<=R){
tr[root].lazy+=c;
tr[root].val+=c;
return ;
}
int midd=(l+r)>>;
if(tr[root].lazy)
pushdown(root);
if(L<=midd)
update(L,R,c,lson);
if(R>midd)
update(L,R,c,rson);
up(root);
}
int query(int L,int R,int root,int l,int r){
if(L<=l&&r<=R){
return tr[root].val;
}
if(tr[root].lazy)
pushdown(root);
int res=;
int midd=(l+r)>>;
if(L<=midd)
res=max(res,query(L,R,lson));
if(R>midd)
res=max(res,query(L,R,rson));
up(root);
return res;
}
int main(){
ios::sync_with_stdio(false);
cin.tie();
int n,m,k;
cin>>n>>m>>k;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
cin>>a[i][j];
sum[i][j]=sum[i][j-]+a[i][j];
}
}
///预处理dp[1]的情况
for(int j=;j<=m-k+;j++){
dp[][j]=sum[][j+k-]-sum[][j-]
+sum[][j+k-]-sum[][j-];
}
for(int i=;i<=n;i++){
memset(tr,,sizeof(tr));
for(int j=;j<=m;j++)
update(j,j,dp[i-][j],,,m);
for(int j=;j<=k;j++)///算一个小预处理 ,为第一个窗口计算做准备
update(,j,-a[i][j],,,m);
///枚举每一个窗口
for(int j=;j<=m-k+;j++){///每个窗口为上一个窗口向右移动一格,代价为去掉左边一个增加右边一个对答案的贡献
dp[i][j]=max(dp[i][j],query(,m,,,m)+sum[i][j+k-]-sum[i][j-]
+sum[i+][j+k-]-sum[i+][j-]);
update(max(,j-k+),j,a[i][j],,,m);///减去左边出队的
update(j+,j+k,-a[i][j+k],,,m);///加上右边入队的
}
}
int ans=;
for(int j=;j<=m;j++)
ans=max(ans,dp[n][j]);
cout<<ans<<endl;
return ;
}

Codeforces Round #620 (Div. 2)F2的更多相关文章

  1. Codeforces Round #620 (Div. 2)

    Codeforces Round #620 (Div. 2) A. Two Rabbits 题意 两只兔子相向而跳,一只一次跳距离a,另一只一次跳距离b,每次同时跳,问是否可能到同一位置 题解 每次跳 ...

  2. Codeforces Round #620 (Div. 2) A-F代码 (暂无记录题解)

    A. Two Rabbits (手速题) #include<bits/stdc++.h> using namespace std; typedef long long ll; int ma ...

  3. Codeforces Round #620 (Div. 2) A. Two Rabbits

    Being tired of participating in too many Codeforces rounds, Gildong decided to take some rest in a p ...

  4. Codeforces Round #620 (Div. 2)E LCA

    题:https://codeforces.com/contest/1304/problem/E 题意:给定一颗树,边权为1,m次询问,每次询问给定x,y,a,b,k,问能否在原树上添加x到y的边,a到 ...

  5. Codeforces Round #620 (Div. 2)D dilworld定理

    题:https://codeforces.com/contest/1304/problem/D 题意:给定长度为n-1的只含’>'和‘<’的字符串,让你构造出俩个排列,俩个排列相邻的数字之 ...

  6. Codeforces Round #540 Div. 3 F2

    考虑将每种颜色构成的极小连通块缩点,然后直接跑树形dp即可,即f[i][0/1]表示子树内是否有颜色向上延伸时删边的方案数.dp时需要去除某点的贡献,最好用前后缀积的做法而不是求逆. 至于如何缩点,假 ...

  7. Codeforces Round #554 (Div. 2) F2. Neko Rules the Catniverse (Large Version) (矩阵快速幂 状压DP)

    题意 有nnn个点,每个点只能走到编号在[1,min(n+m,1)][1,min(n+m,1)][1,min(n+m,1)]范围内的点.求路径长度恰好为kkk的简单路径(一个点最多走一次)数. 1≤n ...

  8. Codeforces Round #620 (Div. 2) D

    构造一个排列,要求相邻之间的数满足给定的大小关系,然后构造出两个序列,一个序列是所有可能的序列中LIS最长的,一个所有可能的序列中LIS最短的 最短的构造方法:我们考虑所有单调递增的部分,可以发现要让 ...

  9. Codeforces Round #620 (Div. 2)E(LCA求树上两点最短距离)

    LCA求树上两点最短距离,如果a,b之间距离小于等于k并且奇偶性与k相同显然YES:或者可以从a先走到x再走到y再走到b,并且a,x之间距离加b,y之间距离+1小于等于k并且奇偶性与k相同也输出YES ...

随机推荐

  1. java 如何爬取百度百科词条内容(java如何使用webmagic爬取百度词条)

    这是老师所布置的作业 说一下我这里的爬去并非能把百度词条上的内容一字不漏的取下来(而是它分享链接的一个主要内容概括...)(他的主要内容我爬不到 也不想去研究大家有好办法可以call me) 例如 互 ...

  2. DevOps - 与敏捷方法区别

    章节 DevOps – 为什么 DevOps – 与传统方式区别 DevOps – 优势 DevOps – 不适用 DevOps – 生命周期 DevOps – 与敏捷方法区别 DevOps – 实施 ...

  3. Oracle之SQL优化专题03-如何看懂SQL的执行计划

    专题第一篇<Oracle之SQL优化专题01-查看SQL执行计划的方法>讲到了查看SQL执行计划的方法,并介绍了各种方法的应用场景,那么这一篇就主要介绍下如何看懂SQL的执行计划.毕竟如果 ...

  4. C#的listview

    listView1.Items.Clear(); ListViewItem listitem = new ListViewItem(字符串);//这是第一列的内容,需要,而且必须通过构造方法添加 ; ...

  5. Node.js NPM 包(Package)

    章节 Node.js NPM 介绍 Node.js NPM 作用 Node.js NPM 包(Package) Node.js NPM 管理包 Node.js NPM Package.json 包是打 ...

  6. hdu 1257 最少拦截系统 求连续递减子序列个数 (理解二分)

    最少拦截系统 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  7. H5页面跳到安卓APP和iosAPP

    if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) { // window.webkit.messagehandlers是js的固定写法, ...

  8. tornado反向解析

    tornado反向解析 在路由中添加name属性,并且不能使用元组路由,应当由tornado.web.url定义路由. app = tornado.web.Application([ (r'/', I ...

  9. easyUI中,z-index失效问题

    1.z-index是css的属性,第一种div设置css的z-index时,是不起作用的,最后设置在style中才起作用了,比较诡异的一件事情. 2.还有一种情况就是,遮盖层在dialog弹出层的下面 ...

  10. 关于数据库text字段

    问题描述: maven项目中,使用MBG代码生成器自动生成的实体类对象时,当数据库中表的字段有 text 类型时,对应到java类中是String类型的,在前端页面通过ajax获取到 json 格式的 ...