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的更多相关文章

  1. HDU 4374 One hundred layer DP的单调队列优化

    One hundred layer Problem Description   Now there is a game called the new man down 100th floor. The ...

  2. 【hdu 4374】One Hundred Layer

    [题目链接] 点击打开链接 [算法] 不难看出,这题可以用动态规划来解决 f[i][j]表示第i行第j列能够取得的最大分数 则如果向右走,状态转移方程为f[i][j]=max{f[i-1][k]+a[ ...

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

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

  4. 【HDOJ】4374 One hundred layer

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

  5. hdu4374One hundred layer (DP+单调队列)

    http://acm.hdu.edu.cn/showproblem.php?pid=4374 去年多校的题 今年才做 不知道这一年都干嘛去了.. DP的思路很好想 dp[i][j] = max(dp[ ...

  6. hdu 4374 单调队列优化动态规划

    思路:我只想说,while(head<=rear&&que[rear].val+sum[j]-sum[que[rear].pos-1]<=dp[i-1][j]+num[i- ...

  7. hdu 4374 单调队列

    求一个最大k连续的子序列和   单调队列 #include<stdio.h> #include<string.h> #include<iostream> using ...

  8. 2012 Multi-University #8

    DP+单调队列优化 E One hundred layer 题意:n*m的矩形,从第一层x位置往下走,每一层都可以往左或往右移动最多k步再往下走,问走到n层时所走路径的最大值. 分析:定义,,注意到m ...

  9. [C6] Andrew Ng - Convolutional Neural Networks

    About this Course This course will teach you how to build convolutional neural networks and apply it ...

随机推荐

  1. OOP思想又一随笔

    现有类再有对象, 类:对现实世界事物的抽象表示,包括事物的状态信息(成员变量)和行为信息(成员方法).我们要让我们的计算机程序设计更有意思,也更有逻辑性,则我们的程序中对事物的描叙就必须符合真实情况, ...

  2. java上下文Context类

    Context在Java中的出现是如此频繁,但其中文翻译"上下文"又是如此诡异拗口,因此导致很多人不是很了解Context的具体含义是指什么,所以很有必要来深究一下这词的含义. 先 ...

  3. 对于iOS 7 隐藏特性和解决之道

    当 iOS7 刚发布的时候,全世界的苹果开发人员都立马尝试着去编译他们的app,接着再花上数月的时间来修复任何出现的故障,甚至重做app.这样的结果,使得人们根本无暇去探究 iOS7 所带来的新东西. ...

  4. MapReduce Join的使用

    一.Map端Join 可连接两个都非常大的数据集之间可使用map端连接,数据在到达map端之前就执行连接操作. 需满足: 两个要连接的数据集都先划分成相同数量的分区,相同的key要保证在同一分区中(每 ...

  5. HDU4280 Island Transport —— 最大流 ISAP算法

    题目链接:https://vjudge.net/problem/HDU-4280 Island Transport Time Limit: 20000/10000 MS (Java/Others)   ...

  6. HDU3567 Eight II —— IDA*算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3567 Eight II Time Limit: 4000/2000 MS (Java/Others)  ...

  7. hdu 1541 Stars 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1541 题目意思:有 N 颗星星,每颗星星都有各自的等级.给出每颗星星的坐标(x, y),它的等级由所有 ...

  8. 用mkdirs创建目录

    import java.io.*; class a { public static void main(String args[]) { createDir("c:/fuck"); ...

  9. I.MX6 u-boot 2009 lvds hdmi lcd 补丁

    /************************************************************************* * I.MX6 u-boot 2009 lvds ...

  10. 洛谷P2473奖励关——状压DP

    题目:https://www.luogu.org/problemnew/show/P2473 还是对DP套路不熟悉... 像这种前面影响后面,而后面不影响前面的问题就应该考虑倒序递推: 看n只有15那 ...