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. 豆瓣面试题strstr)

    /*(豆瓣2013面试题strstr) 有一个在给定字符串中查找子串的函数strstr, 该函数从给定的字符串src中查找substr并返回一个整数, 指明substr第一次出现的位置(从0开始计数) ...

  2. appium部分api

    转自:http://www.aichengxu.com/view/41510 使用的语言是java,appium的版本是1.3.4,java-client的版本是java-client-2.1.0,建 ...

  3. ViewGroup如何分发事件

    dispatchTouchEvent事件派发显示隧道方式.再是冒泡方式隧道方式传递,直道某一个元素消耗此事件,由上至下逐层分发视图.冒泡方式传递,当某个视图消耗事件后其return boolean 是 ...

  4. HDU 2601An easy problem-素数的运用,暴力求解

    id=17433" target="_blank" style="color:blue; text-decoration:none">An ea ...

  5. python day- 5 字典(dic)的 增删改查 及 操作方法

    字典(dic) 1.定义及格式 用{ }大括号括起来的,由key:value 来保存数据的就是 字典(dic) eg:dic = {"及时雨" : "宋江" , ...

  6. COGS28 [NOI2006] 最大获利[最大权闭合子图]

    [NOI2006] 最大获利 ★★★☆   输入文件:profit.in   输出文件:profit.out   简单对比时间限制:2 s   内存限制:512 MB [问题描述] 新的技术正冲击着手 ...

  7. map数据的分组,list数据排序 数据筛选

    sfit0144 (李四) 2015-01-10 18:00:251Sfit0734 (Sfit0734) 2015-01-10 18:00:38go homesfit0144 (李四) 2015-0 ...

  8. 使用PHP对word文档进行操作的方法

    使用php时,因为加密等原因,如果直接用FILE后者OPEN等函数读取WORD的话往往是乱码,原来要使用COM 这是我简单的一个读取并存储到新的WORD上的文件<? // 建立一个指向新COM组 ...

  9. 一步一步学Silverlight 2系列(28):图片处理

    概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...

  10. STL Algorithms 之 unique

    C++的文档中说,STL中的unique是类似于这样实现的: template <class ForwardIterator> ForwardIterator unique ( Forwa ...