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 ;
}

最新文章

  1. JAVA实现国际化
  2. Usart的单线半双工模式(stm32F10x系列)
  3. js日历表
  4. Android 使用java.net.socket 的接收问题
  5. ERROR 2002 (HY000): Can&#39;t connect to local MySQL server through socket &#39;/var/lib
  6. eoe项目结构
  7. NSDictionary 初始化
  8. Cocos2d-x 3.0 场景切换
  9. Shell编程实践之批量安装JDK
  10. 强力推荐!那些你不能错过的 GitHub 插件和工具
  11. (2).NET CORE微服务 Micro-Service ---- .NetCore启动配置 和 .NetCoreWebApi
  12. Oracle 24角色管理
  13. Nginx 负载均衡与反向代理
  14. 解决github网站打开慢的问题
  15. 20165303学习基础和C语言基础调查
  16. 文件I/0缓冲
  17. python测试开发django-38.多对多(ManyToManyField)查询
  18. 解决 slf4j + log4j 在云服务上打印乱码
  19. Window 2008 R2组策略之一——组策略管理控制台
  20. Xss和Csrf介绍

热门文章

  1. LNMP安装成功的界面
  2. Robot Motion(imitate)
  3. [Effective JavaScript 笔记]第54条:将undefined看做“没有值”
  4. Unity3D 4.x 使用Mecanim实现连击
  5. BZOJ 1452 [JSOI2009] Count
  6. C#静态static的用法
  7. 如何用BMFont制作图片字
  8. win平台检查内存泄露
  9. 在SQLServer处理中的一些问题及解决方法 NEWSEQUENTIALID()
  10. Python多线程(3)——Queue模块