One hundred layer

Problem Description
 
Now there is a game called the new man down 100th floor. The rules of this game is:
  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.
 
Input
 
The first line of each case has four integer N, M, X, T(1<=N<=100, 1<=M<=10000, 1<=X, T<=M). N indicates the number of layers; M indicates the number of parts. At first you are in the X-th part. You can move at most T parts in every floor in only one direction.
Followed N lines, each line has M integers indicating the score. (-500<=score<=500)
 
Output
 
Output the highest score you can get.
 
Sample Input
 
3 3 2 1
7 8 1
4 5 6
1 2 3
 
Sample Output
 
29
 

题意:

  给你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的单调队列优化的更多相关文章

  1. 洛谷P3975 跳房子 [DP,单调队列优化,二分答案]

    题目传送门 跳房子 题目描述 跳房子,也叫跳飞机,是一种世界性的儿童游戏,也是中国民间传统的体育游戏之一. 跳房子的游戏规则如下: 在地面上确定一个起点,然后在起点右侧画 n 个格子,这些格子都在同一 ...

  2. Codeforces 487B Strip (ST表+线段树维护DP 或 单调队列优化DP)

    题目链接 Strip 题意   把一个数列分成连续的$k$段,要求满足每一段内的元素最大值和最小值的差值不超过$s$, 同时每一段内的元素个数要大于等于$l$, 求$k$的最小值. 考虑$DP$ 设$ ...

  3. HDU 4374 One hundred layer(单调队列DP)

    题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=116242#problem/E 题意:差不多就是男人勇下百层的游戏.从第一层到最 ...

  4. Easy Climb UVA - 12170 滚动dp +离散化+ 单调队列优化

    E.Easy Climb Somewhere in the neighborhood we have a very nice mountain that gives a splendid view o ...

  5. P2034 选择数字——线性dp(单调队列优化)

    选择数字 题目描述 给定一行 \(n\) 个非负整数 \(a[1]...a[n]\) .现在你可以选择其中若干个数,但不能有超过 \(k\) 个连续的数字被选择.你的任务是使得选出的数字的和最大. 输 ...

  6. ZOJ2067 经典 DP(单调队列优化)

    题目:一个由‘.’和‘#’组成矩形,统计里面'.'组成的矩形的个数. 点击打开链接 自己写挂了,懒得搞了 #include <stdio.h> #include <string.h& ...

  7. [小明打联盟][斜率/单调队列 优化dp][背包]

    链接:https://ac.nowcoder.com/acm/problem/14553来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时 ...

  8. 【HDOJ】4374 One hundred layer

    线性DP,使用单调队列优化. /* 4374 */ #include <iostream> #include <sstream> #include <string> ...

  9. 【单调队列优化dp】HDU 3401 Trade

    http://acm.hdu.edu.cn/showproblem.php?pid=3401 [题意] 知道之后n天的股票买卖价格(api,bpi),以及每天股票买卖数量上限(asi,bsi),问他最 ...

随机推荐

  1. SYN攻击TIME_WAIT防御。

    #! /bin/bash /bin/netstat -anput | grep TIME_WAIT >time_wait.txt /bin/cat time_wait.txt |awk '{pr ...

  2. Visual Studio Online Integrations-Sync and migration

      原文:http://www.visualstudio.com/zh-cn/explore/vso-integrations-directory-vs

  3. jQuery.snowflake雪花飘落插件

    一.前言 前言:最近圣诞节来临,需要在页面上应用一个雪花飘落的效果,做之前产品经理给了我网络上的一个demo,地址是http://demo.lanrenzhijia.com/demo/1225/sd/ ...

  4. 解读JSP的解析过程

    解读JSP的解析过程 互联网上,这方面的资料实在太少了,故把自己研究的一些结果公布出来. 首先,问大家几个问题,看大家能不能回答出来,或者在网上能不能找到答案: 1.page.include.tagl ...

  5. <转>错误 x error LNK1104: 无法打开文件“E:\xxxx\Debug\xxxx.exe”

    刚刚还好好的,怎么突然就出现这样的错误, 后来分析原因, 第一:查看那个exe文件是否存在, 第二:查看那个文件或者那个文件所在的文件夹是否打开或者改名字等等操作占用着这个文件. 第三:重新清理并生成 ...

  6. 2000多万个微信号被封全面禁止"集赞" 微信雷霆行动这次玩真的

    微信雷霆行动自年初启动了打击网络黑色产业链以来,微信累计封停了2000万个招嫖账号,3万个假货公众账号,切实保护用户利益.你曾经中过招吗?Yes or No?说说你的看法吧. 同时,微信从9日起开始升 ...

  7. CocoStudio基础教程(4)骨骼动画的动态换肤

    1.概述 游戏中人物的状态会发生改变,而这种改变通常要通过局部的变化来表现出来.比如获得一件装备后人物形象的改变,或者战斗中武器.防具的损坏等.这些变化的实现就要通过动态换肤来实现. 2.运行到程序 ...

  8. show processlist 其中status详解(适用于所有概况)

    mysql show processlist分析 2011-04-11 16:13:00 分类: Mysql/postgreSQL mysql> show processlist; +—–+—— ...

  9. Dialog类介绍

    Dialog类实现为一个简单的漂浮窗口,完全在Activity中创建.使用基本的Dialog类,你可以创建一个新的实例并设定标题和布局,如下所示: Dialog d = new Dialog(MyAc ...

  10. 淘宝(阿里百川)手机客户端开发日记第五篇 SharedPreferences使用详解

    我们知道,Android中数据存储技术由于如下几种 1 使用SharedPreferences存储数据 2 文件存储数据 3 SQLite数据库存储数据 4 使用ContentProvider存储数据 ...