One hundred layer HDU - 4374
$sum[i][j][k]$表示第i层第j到k列的和
$ans[i][j]$表示第i层最终停留在第j列的最大值,那么显然$ans[i][j]=max(ans[i-1][j-t]+sum[i][j-t][j],..,ans[i-1][j+t]+sum[i][j+t][j])$
显然,直接按照方程做,时间复杂度$O(nmt)$,是无法通过的。但是看到max,可以想到用一些RMQ的方法优化。
这里重要的是一个分解(未想到):
$ans1[i][j]$表示第i层下来后向右走并停留在第j列的最大值
$ans2[i][j]$表示第i层下来后向左走并停留在第j列的最大值
求出每一行的ans1和ans2后,那么$ans[i][j]=max(ans1[i][j],ans2[i][j])$
那么:(为了方便,a[j]表示第i行第j列)
$ans1[i][j]=max(ans[i-1][j]+a[j],..,ans[i-1][j-t]+a[j]+...+a[j-t])$
$ans2[i][j]=max(ans[i-1][j]+a[j],..,ans[i-1][j+t]+a[j]+..+a[j+t])$
还要做一些处理:(貌似别人的代码都是直接上啊?难道状态没定义好?)
对于ans1:
t=2时,
$$\begin{equation}\begin{split}ans1[i][1]&=max(ans[i-1][1]+a[1])\\
&=max(ans[i-1][1])+a[1]\end{split}\end{equation}$$
$$\begin{equation}\begin{split}ans1[i][2]&=max(ans[i-1][1]+a[1]+a[2],ans[i-1][2]+a[2])\\
&=max(ans[i-1][1],ans[i-1][2]-a[1])+a[1]+a[2]\end{split}\end{equation}$$
...
对于ans2:
t=1
$$\begin{equation}\begin{split}ans2[i][m]&=max(ans[i-1][m]+a[m])\\&=max(ans[i-1][m])+a[m]\end{split}\end{equation}$$
$$\begin{equation}\begin{split}ans2[i][m-1]&=max(ans[i-1][m-1]+a[m-1],ans[i-1][m]+a[m]+a[m-1])\\&=max(ans[i-1][m],ans[i-1][m-1]-a[m])+a[m]+a[m-1]\end{split}\end{equation}$$
$$\begin{equation}\begin{split}ans[i][m-2]&=max(ans[i-1][m-2]+a[m-2],ans[i-1][m-1]+a[m-2]+a[m-1])\\&=max(ans[i-1][m-2]-a[m]-a[m-1],ans[i-1][m-1]-a[m])+a[m]+a[m-1]+a[m-2]\end{split}\end{equation}$$
.....
这样,优化的方法就比较明显了,用一个单调队列维护滑动窗口的最小值即可。
错误次数:很多
查错时间:>1小时
错误原因:63行数组名打错,ans2打成ans1,单调队列复制粘贴时未修改
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
typedef pair<int,int> P;
int l,r,n,m,x,y,a[][],ans[][],ans1[][],ans2[][],sum[];
int anss;
P q[],t;
int main()
{
int i,j;
while(scanf("%d%d%d%d",&n,&m,&x,&y)==)
{
anss=-0x3f3f3f3f;
memset(ans,,sizeof(ans));
for(i=;i<=n;i++)
for(j=;j<=m;j++)
scanf("%d",&a[i][j]);
ans[][x]=a[][x];
for(i=;i<=y;i++)
{
if(x+i<=m) ans[][x+i]=ans[][x+i-]+a[][x+i];
if(x-i>=) ans[][x-i]=ans[][x-i+]+a[][x-i];
}
for(i=;i<=n;i++)
{
for(j=;j<=m;j++)
sum[j]=sum[j-]+a[i][j];
l=r=;
for(j=;j<=y+;j++)
{
t=P(ans[i-][j]-sum[j-],j);
while(l<r&&q[r-].first<=t.first) --r;
q[r++]=t;
ans1[i][j]=q[l].first+sum[j];
}
for(j=y+;j<=m;j++)
{
if(l<r&&q[l].second<j-y) l++;
t=P(ans[i-][j]-sum[j-],j);
while(l<r&&q[r-].first<=t.first) --r;
q[r++]=t;
ans1[i][j]=q[l].first+sum[j];
}
sum[m+]=;
for(j=m;j>=;j--)
sum[j]=sum[j+]+a[i][j];
l=r=;
for(j=m;j>=m-y;j--)
{
t=P(ans[i-][j]-sum[j+],j);
while(l<r&&q[r-].first<=t.first) --r;
q[r++]=t;
ans2[i][j]=q[l].first+sum[j];
}
for(j=m-y-;j>=;j--)
{
if(l<r&&q[l].second>j+y) l++;
t=P(ans[i-][j]-sum[j+],j);
while(l<r&&q[r-].first<=t.first) --r;
q[r++]=t;
ans2[i][j]=q[l].first+sum[j];
}
for(j=;j<=m;j++)
ans[i][j]=max(ans1[i][j],ans2[i][j]);
}
for(j=;j<=m;j++)
anss=max(anss,ans[n][j]);
printf("%d\n",anss);
}
return ;
}
sum[i][j]表示第i层第j到k列的和
ans[i][j]表示第i层停留在第j列的最大值
ans[i][j]=max(ans[i-1][j-t]+sum[i][j-t][j],..,ans[i-1][j+t]+sum[i][j+t][j])
**分解:
ans1[i][j]表示第i层下来后向右走并停留在第j列的最大值
ans2..左..
ans1[i][j]=max(ans[i-1][j]+sum[i][j][j],..,ans[i-1][j-t]+sum[i][j-t][j])
t=2
ans1[i][1]=max(ans[i-1][1]+a[1])
=max(ans[i-1][1])+a[1]
ans1[i][2]=max(ans[i-1][1]+a[1]+a[2],ans[i-1][2]+a[2])
=max(ans[i-1][1],ans[i-1][2]-a[1])+a[1]+a[2]
//=max(ans[i-1][1]+a[1],ans[i-1][2])+a[2]
//=max(ans1[i][1],ans[i-1][2])+a[2]
ans1[i][3]=max(ans[i-1][1]+a[1]+a[2]+a[3],ans[i-1][2]+a[2]+a[3],ans[i-1][3]+a[3])
=max(ans[i-1][1],ans[i-1][2]-a[1],ans[i-1][3]-a[1]-a[2])+a[1]+a[2]+a[3]
//=max(ans[i-1][1]+a[1]+a[2],ans[i-1][2]+a[2],ans[i-1][3])+a[3]
//=max(ans1[i][2],ans[i-1][3])+a[3]
ans1[i][4]=max(ans[i-1][2]+a[2]+a[3]+a[4],ans[i-1][3]+a[3]+a[4],ans[i-1][4]+a[4])
=max(ans[i-1][2]-a[1],ans[i-1][3]-a[1]-a[2],ans[i-1][4]-a[1]-a[2]-a[3])+a[1]+a[2]+a[3]+a[4]
//=max(ans[i-1][2]+a[2]+a[3],ans[i-1][3]+a[3],ans[i-1][4])+a[4]
ans2[i][j]=max(ans[i-1][j]+a[j],ans[i-1][j+1]+a[j]+a[j+1],..,ans[i-1][j+t]+a[j]+..+a[j+t])
t=1
ans2[i][m]=max(ans[i-1][m]+a[m])
=max(ans[i-1][m])+a[m]
ans2[i][m-1]=max(ans[i-1][m-1]+a[m-1],ans[i-1][m]+a[m]+a[m-1])
=max(ans[i-1][m],ans[i-1][m-1]-a[m])+a[m]+a[m-1]
ans[i][m-2]=max(ans[i-1][m-2]+a[m-2],ans[i-1][m-1]+a[m-2]+a[m-1])
=max(ans[i-1][m-2]-a[m]-a[m-1],ans[i-1][m-1]-a[m])+a[m]+a[m-1]+a[m-2]
6 3 2 2
7 8 1 7 8 1
4 5 6 4 5 6
1 2 3 1 2 3
t=1
ans[2][1]=max(ans[1][1]+sum[2][1][1],ans[1][2]+sum[2][2][1])
ans[2][2]=max(ans[1][1]+sum[2][1][2],ans[1][2]+sum[2][2][2],ans[1][3]+sum[2][3][2])
ans[2][3]=max(ans[1][2]+sum[2][2][3],ans[1][3]+sum[2][3][3],ans[1][4]+sum[2][4][3])
t=2
ans[2][1]=max(ans[1][1]+sum[2][1][1],ans[1][2]+sum[2][1][2],ans[1][3]+sum[2][1][3])
ans[2][2]=max(ans[1][1]+sum[2][1][2],ans[1][2]+sum[2][2][2],ans[1][3]+sum[2][2][3],ans[1][4]+sum[2][2][4])
ans[2][3]=max(ans[1][1]+sum[2][1][3],ans[1][2]+sum[2][2][3],ans[1][3]+sum[2][3][3],ans[1][4]+sum[2][3][4],ans[1][5]+sum[2][3][5])
ans[2][4]=max(ans[1][2]+sum[2][2][4],ans[1][3]+sum[2][3][4],ans[1][4]+sum[2][4][4],ans[1][5]+sum[2][4][5],ans[1][6]+sum[2][4][6])
t=2
ans[2][1]=max(ans[1][1]+a[2][1], ans[1][2]+a[2][1]+a[2][2], ans[1][3]+a[2][1]+a[2][2]+a[2][3])
ans[2][2]=max(ans[1][1]+a[2][1]+a[2][2], ans[1][2]+a[2][2], ans[1][3]+a[2][2]+a[2][3], ans[1][4]+a[2][2]+a[2][3]+a[2][4])
ans[2][3]=max(ans[1][1]+a[2][1]+a[2][2]+a[2][3],ans[1][2]+a[2][2]+a[2][3], ans[1][3]+a[2][3], ans[1][4]+a[2][3]+a[2][4], ans[1][5]+a[2][3]+a[2][4]+a[2][5])
ans[2][4]=max(ans[1][2]+a[2][2]+a[2][3]+a[2][4],ans[1][3]+a[2][3]+a[2][4], ans[1][4]+a[2][4], ans[1][5]+a[2][4]+a[2][5], ans[1][6]+a[2][4]+a[2][5]+a[2][6])
One hundred layer HDU - 4374的更多相关文章
- HDU 4374 One hundred layer DP的单调队列优化
One hundred layer Problem Description Now there is a game called the new man down 100th floor. The ...
- 【hdu 4374】One Hundred Layer
[题目链接] 点击打开链接 [算法] 不难看出,这题可以用动态规划来解决 f[i][j]表示第i行第j列能够取得的最大分数 则如果向右走,状态转移方程为f[i][j]=max{f[i-1][k]+a[ ...
- HDU 4374 One hundred layer(单调队列DP)
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=116242#problem/E 题意:差不多就是男人勇下百层的游戏.从第一层到最 ...
- 【HDOJ】4374 One hundred layer
线性DP,使用单调队列优化. /* 4374 */ #include <iostream> #include <sstream> #include <string> ...
- hdu4374One hundred layer (DP+单调队列)
http://acm.hdu.edu.cn/showproblem.php?pid=4374 去年多校的题 今年才做 不知道这一年都干嘛去了.. DP的思路很好想 dp[i][j] = max(dp[ ...
- hdu 4374 单调队列优化动态规划
思路:我只想说,while(head<=rear&&que[rear].val+sum[j]-sum[que[rear].pos-1]<=dp[i-1][j]+num[i- ...
- hdu 4374 单调队列
求一个最大k连续的子序列和 单调队列 #include<stdio.h> #include<string.h> #include<iostream> using ...
- 2012 Multi-University #8
DP+单调队列优化 E One hundred layer 题意:n*m的矩形,从第一层x位置往下走,每一层都可以往左或往右移动最多k步再往下走,问走到n层时所走路径的最大值. 分析:定义,,注意到m ...
- [C6] Andrew Ng - Convolutional Neural Networks
About this Course This course will teach you how to build convolutional neural networks and apply it ...
随机推荐
- 使用Javamelody验证struts-spring框架与springMVC框架下action的訪问效率
在前文中我提到了关于为何要使用springMVC的问题,当中一点是使用springMVC比起原先的struts+spring框架在效率上是有优势的.为了验证这个问题,我做了两个Demo来验证究竟是不是 ...
- OpenCV2.3.1在CentOS6.5下的安装
安装的linux版本号是centos6.5.选择的是opencv2.3.1.不是非常新的版本号. 由于在安装opencv2.4.9的时候.make的过程中出现了问题. 一:安装依赖包 依赖包用yum安 ...
- activity栈管理的3种方式
一.背景 在android开发过程最经常使用的组件非activity莫属. 通过分析activity的各种跳转,执行同学能够分析用户的各种行为.更重要的一点是在做插件化的过程中,我们经常会对activ ...
- 网页 H5“线条” 特效实现方式(canvas-nest)
先上图 (看博客空白处也可以呦): 前一阵浏览网站的时候,发现了这个好玩的东西,一直想找找怎么实现的,今天忙里偷闲,上网搜了一下,发现实现起来特别简单. 只需要在网页body里引入一个<scri ...
- 初识Restful(学习笔记)
什么是Restful? REST -- Resource Representational State Transfer(表现层状态转移) 本质上是一种优雅的URL表达方式,描述资源的状态和状态的转移 ...
- Wordpress播客网站搭建
- numpy计算
import numpy as np import cv2 from PIL import Image #lenna.jpg # Create a black image #img=np.zeros( ...
- strncpy和strlen的可能的实现
#include <stdio.h> #include <stdlib.h>//为避免与标准库中的函数发生混淆,我将它们命名为stringNCopy和stringLength ...
- 在Java中如何编写回调函数,以及回调函数的简单应用
import static java.lang.System.out; import static java.lang.System.err; import java.util.logging.Lev ...
- Android Studio解决导入项目非常慢
Android Studio比Eclipse ADT有巨大的优势.Android Studio原生支持使用Gradle来构建项目,使用动态语言Groovy定义项目构建的过程,避免了build.xml文 ...