HDU 4374 One hundred layer DP的单调队列优化
One hundred layer
1. At first you are at the 1st floor. And the floor moves up. Of course you can choose which part you will stay in the first time.
2. Every floor is divided into M parts. You can only walk in a direction (left or right). And you can jump to the next floor in any part, however if you are now in part “y”, you can only jump to part “y” in the next floor! (1<=y<=M)
3. There are jags on the ceils, so you can only move at most T parts each floor.
4. Each part has a score. And the score is the sum of the parts’ score sum you passed by.
Now we want to know after you get the 100th floor, what’s the highest score you can get.
Followed N lines, each line has M integers indicating the score. (-500<=score<=500)
7 8 1
4 5 6
1 2 3
题意:
给你n*m的图,起始位置在第一行的第x个位置,现在你可以选择一个方向至多走T个位置然后走向下一行,直到第n行
路过的格子里的值总和最大是多少
题解:
首先想到dp[i][j]表示到达当前(i,j)格子的最大答案,那么最后答案显然了
思考如何得到(i,j)的最优答案
他可以是从左边上一层走下来再向右走到j位置,且走过不超过T,也可以是右边
对于左边:dp[i][j] = dp[i-1][k] - sum[i][k-1] + sum[i][j];
dp[i-1][k] - sum[i][k-1]这一块是上一层,和当前层没有任何关系,我们可以预处理啊
那么我们维护一个大小T的单调队列,左边右边扫一波就好了
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include<queue>
using namespace std;
const int N = , M = 1e4+, mod = ,inf = 2e9;
typedef long long ll; int n,m,x,t,a[N][M],sum[N][M],dp[N][M];
int main() { while(scanf("%d%d%d%d",&n,&m,&x,&t)!=EOF) {
for(int i=;i<=n;i++)
for(int j=;j<=m;j++) scanf("%d",&a[i][j]);
for(int i=;i<=n;i++) {
sum[i][] = ;
for(int j=;j<=m;j++) sum[i][j] = sum[i][j-] + a[i][j];
}
for(int i=;i<=n;i++) for(int j=;j<=m;j++) dp[i][j] = -inf;
for(int i=x;i>=&&i>=x-t;i--)
dp[][i] = sum[][x] - sum[][i-];
for(int i=x;i<=m&&i<=x+t;i++)
dp[][i] = sum[][i] - sum[][x-]; deque<int >q;
for(int i=;i<=n;i++) {
//从左向右 while(!q.empty()) q.pop_back();
dp[i][] = dp[i-][] + a[i][];
q.push_back();
for(int j=;j<=m;j++) {
while(!q.empty()&&j-q.front()>t) q.pop_front();
int now = dp[i-][j] - sum[i][j-];
while(!q.empty()&&dp[i-][q.back()]-sum[i][q.back()-]<=now) q.pop_back();
q.push_back(j);
int pos = q.front();
dp[i][j] = max(dp[i][j],dp[i-][pos]-sum[i][pos-]+sum[i][j]);
} while(!q.empty()) q.pop_back();
q.push_back(m);
dp[i][m] = max(dp[i][m],dp[i-][m]+a[i][m]); for(int j=m-;j>=;j--) {
while(!q.empty()&&q.front()-j>t) q.pop_front();
int now = dp[i-][j] + sum[i][j];
while(!q.empty()&&dp[i-][q.back()]+sum[i][q.back()]<=now) q.pop_back();
q.push_back(j);
int pos = q.front();
dp[i][j] = max(dp[i][j],dp[i-][pos]+sum[i][pos]-sum[i][j-]);
} }
int ans = -inf;
for(int i=;i<=m;i++) ans = max(ans,dp[n][i]);
printf("%d\n",ans);
}
return ;
}
HDU 4374 One hundred layer DP的单调队列优化的更多相关文章
- 洛谷P3975 跳房子 [DP,单调队列优化,二分答案]
题目传送门 跳房子 题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 n 个格子,这些格子都在同一 ...
- Codeforces 487B Strip (ST表+线段树维护DP 或 单调队列优化DP)
题目链接 Strip 题意 把一个数列分成连续的$k$段,要求满足每一段内的元素最大值和最小值的差值不超过$s$, 同时每一段内的元素个数要大于等于$l$, 求$k$的最小值. 考虑$DP$ 设$ ...
- HDU 4374 One hundred layer(单调队列DP)
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=116242#problem/E 题意:差不多就是男人勇下百层的游戏.从第一层到最 ...
- Easy Climb UVA - 12170 滚动dp +离散化+ 单调队列优化
E.Easy Climb Somewhere in the neighborhood we have a very nice mountain that gives a splendid view o ...
- P2034 选择数字——线性dp(单调队列优化)
选择数字 题目描述 给定一行 \(n\) 个非负整数 \(a[1]...a[n]\) .现在你可以选择其中若干个数,但不能有超过 \(k\) 个连续的数字被选择.你的任务是使得选出的数字的和最大. 输 ...
- ZOJ2067 经典 DP(单调队列优化)
题目:一个由‘.’和‘#’组成矩形,统计里面'.'组成的矩形的个数. 点击打开链接 自己写挂了,懒得搞了 #include <stdio.h> #include <string.h& ...
- [小明打联盟][斜率/单调队列 优化dp][背包]
链接:https://ac.nowcoder.com/acm/problem/14553来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时 ...
- 【HDOJ】4374 One hundred layer
线性DP,使用单调队列优化. /* 4374 */ #include <iostream> #include <sstream> #include <string> ...
- 【单调队列优化dp】HDU 3401 Trade
http://acm.hdu.edu.cn/showproblem.php?pid=3401 [题意] 知道之后n天的股票买卖价格(api,bpi),以及每天股票买卖数量上限(asi,bsi),问他最 ...
随机推荐
- 宿主机为linux、windows分别实现VMware三种方式上网(转)
一.VMware三种方式工作原理1 Host-only连接方式 让虚机具有与宿主机不同的各自独立IP地址,但与宿主机位于不同网段,同时为宿主主机新增一个IP地址,且保证该IP地址与各虚机IP地址位于 ...
- IE7下,input元素相对父级元素错位解决办法
原因: 当input仅仅包含父元素,父元素拥有margin属性时,IE7的input就会错误的继承margin属性. 解决办法: 给input元素外面套一个span,label这样的内联元素,这样就会 ...
- [原]Android官方图片加载利器BitmapFun解析
通过BitmapFun在项目中使用,结合代码了解一下BitmapFun加载图片的原理,以及最佳使用实践.本文说明不包括BitmapFun的缓存部分. Android开发在使用ListView和Grid ...
- meta中的viewport指令
网页手机wap2.0网页的head里加入下面这条元标签,在iPhone的浏览器中页面将以原始大小显示,并不允许缩放. <meta name="viewport" conten ...
- TableInputFormat分片及分片数据读取源码级分析
我们在MapReduce中TextInputFormat分片和读取分片数据源码级分析 这篇中以TextInputFormat为例讲解了InputFormat的分片过程以及RecordReader读取分 ...
- Internet信息服务找不到
最近我的电脑也出现了Internet信息服务找不到的情况,在网络上查了很多方法都没一个正确的,后面通过下面的方法我成功了,故此我把这个经历也分享给大家,希望能够帮到您. 控制面板里“->添加/删 ...
- 程序员必读:Linux内存管理剖析
现在的服务器大部分都是运行在Linux上面的,所以作为一个程序员有必要简单地了解一下系统是如何运行的. 对于内存部分需要知道: 地址映射 内存管理的方式 缺页异常 先来看一些基本的知识,在进程看来,内 ...
- 对target="framename"的理解(实现分页的demo)
先上图,说明一下我主要想实现什么功能. 一.演示图 演示首页: 演示内容页(包括按钮切换页+模板内容页): 演示首页到演示内容页的一个演变过程:
- DButils实现查询和新增
public static Adttendance DBSql(String data) throws SQLException { String url = "j ...
- HTML快速入门3
四.表格 (Table) 1. 表格的基本形式 表由 <table> 开始, </table> 结束,表的内容由 <tr>,<th> 和 <td& ...