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 ...
随机推荐
- Arcgis Engine(ae)接口详解(3):featureClass的feature编辑和删除
//由于测试数据不完善,featureClass在此要只设null值,真实功能要设实际的值 IFeatureClass featureClass = null; //获取某个字段的索引,后面取字段值用 ...
- 【配置关系】—Entity Framework实例详解
实体间的关系,简单来说无非就是一对一.一对多.多对多,根据方向性来说又分为双向和单向.Code First在实体关系上有以下约定: 1. 两个实体,如果一个实体包含一个引用属性,另一个实体包含一个集合 ...
- hadoop的一般端口使用
- 0 lrwxrwxrwx. 1 root root 13 Nov 20 12:44 scala -> scala-2.12.4
符号链接的文件属性相同,真正的权限属性由符号链接所指向的实际文件决定.
- 探索C++的底层机制
探索C++的底层机制 在看这篇文章之前,请你先要明白一点:那就是c++为我们所提供的各种存取控制仅仅是在编译阶段给我们的限制,也就是说是编译器确保了你在完成任务之前的正确行为,如果你的行为不正确,那么 ...
- redis03----集合 set 相关命令
集合 set 相关命令 集合的性质: 唯一性,无序性,确定性 注: 在string和link的命令中,可以通过range 来访问string中的某几个字符或某几个元素 但,因为集合的无序性,无法通过下 ...
- FZU1901 Period II —— KMP next数组
题目链接:https://vjudge.net/problem/FZU-1901 Problem 1901 Period II Accept: 575 Submit: 1495Time Lim ...
- java如何判断字符串是否为空(小知识)
方法一: 最多人使用的一个方法, 直观, 方便, 但效率很低: if(s == null ||"".equals(s));方法二: 比较字符串长度, 效率高, 是我知道的最好一个方 ...
- FINDSTR 命令使用详解
Findstr 使用正则表达式搜索文件中的文本模式. 语法 findstr [/b] [/e] [/l] [/r] [/s] [/i] [/x] [/v] [/n] [/m] [/o] [/p] [/ ...
- vue 基本知识整理
1 每个Vue.js应用都是通过构造函数Vue创建一个Vue的根实例 2 可以扩展Vue构造器,从而使用预定义选项创建可复用的组件构造器 所有的Vue.js组件其实都是被扩展的Vue实例 每一个VUE ...