题目传送门(内部题23)


输入格式

第一行有$2$个整数$n,m$。
接下来有$n$行,每行$m$个整数,表示$a$数组。
接下来有$n$行,每行$m$个整数,表示$b$数组。


输出格式

一行一个整数表示答案。


样例

样例输入:

3 3
0 6 8
1 6 1
0 6 8
0 1 2
3 4 5
0 6 7

样例输出:

21


数据范围与提示

样例解释:

最优路径$(2,3)\rightarrow (3,2)\rightarrow (3,3)$。
最优答案$5+6+7+|3-2|+|2-3|+|3-3|+|3-2|=21$。

数据范围:

对于所有数据,$1\leqslant n,m\leqslant 2\times {10}^3,0\leqslant a_i\leqslant {10}^6,0\leqslant b_i\leqslant {10}^6$。
保证至少存在一个地区$a[i][j]>0$,所有$a[i][j]=0$的地区满足$b[i][j]=0$。


题解

首先,为使国王心情更舒畅,我们所要规划的路线一定是在离散化之后$a[i][j]$每次只增加$1$的一条路线,那么你可能会想到建边跑最长路,但是显然这样就$TLE$掉了。

所以我们考虑$DP$,定义$dp[i][j]$表示到达点$(i,j)$的最大吸引度之和。

那么我们可以暴力转移,枚举每一个点,最劣时间复杂度是$\Theta(n^2m^2)$,还是不行。

所以考虑进行优化。

考虑对于点$(i,j)$,要从点$(i',j')$转移得来,那么将分为下面四种情况:

可能从左上,右上,左下,右下四个方向进行转移。

那么你可能会想到用二维树状数组,时间复杂度:$\Theta(n\times m\times \log n \times \log m)$,这样你就拿到了$80$分。

那么考虑满分算法。

分别维护四个最大值:

  $(1,1)−(i,j):dp[i'][j']−i−j$的最大值。
  $(1,j)−(i,m):dp[i'][j']−i+j$的最大值。
  $(i,1)−(n,j):dp[i'][j']+i−j$的最大值。
  $(i,j)−(n,m):dp[i'][j']+i+j$的最大值。

转移的时候从这$4$个最大值中转直接转移过来即可。

那你可能会存在疑问,如果$(i',j')$在$(i,j)$的左上方,但是我们却从维护的左下角中的最大之中转移过来了怎么办?

我会告诉你,这种状况是一定不会发生的,仔细计算一下即可发现从右下转移一定没有从左上转移得到的值更大。

到此这道题就轻松解决了。

对于下面我的代码,我把所有有$a[i][j]$的点压入了队列,然后进行排序,所以$dp$只有一维。

时间复杂度:$\Theta(n\times m)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
struct node{long long x,y,v,w;}que[4000001];
int n,m;
long long a[2001][2001],b[2001][2001];
long long num,prem[4],maxn[4];
long long dp[4000001];
long long ans;
bool cmp(node a,node b){return a.v<b.v;}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%lld",&a[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%lld",&b[i][j]);
if(a[i][j])que[++num]=(node){i,j,a[i][j],b[i][j]};
}
sort(que+1,que+num+1,cmp);
int lft;
dp[1]=que[1].w;
maxn[0]=max(maxn[0],dp[1]+que[1].x+que[1].y);
maxn[1]=max(maxn[1],dp[1]-que[1].x+que[1].y);
maxn[2]=max(maxn[2],dp[1]+que[1].x-que[1].y);
maxn[3]=max(maxn[3],dp[1]-que[1].x-que[1].y);
for(int i=2;i<=num;i++)
{
if(que[i].v!=que[i-1].v)
{
lft=i;
break;
}
dp[i]=que[i].w;
maxn[0]=max(maxn[0],dp[i]+que[i].x+que[i].y);
maxn[1]=max(maxn[1],dp[i]-que[i].x+que[i].y);
maxn[2]=max(maxn[2],dp[i]+que[i].x-que[i].y);
maxn[3]=max(maxn[3],dp[i]-que[i].x-que[i].y);
}
for(int i=lft;i<=num;i++)
{
if(que[i].v!=que[i-1].v)
for(int j=0;j<4;j++)
{
prem[j]=maxn[j];
maxn[j]=0;
}
dp[i]=max(max(prem[0]-que[i].x-que[i].y,prem[1]+que[i].x-que[i].y),max(prem[2]-que[i].x+que[i].y,prem[3]+que[i].x+que[i].y))+que[i].w;
maxn[0]=max(maxn[0],dp[i]+que[i].x+que[i].y);
maxn[1]=max(maxn[1],dp[i]-que[i].x+que[i].y);
maxn[2]=max(maxn[2],dp[i]+que[i].x-que[i].y);
maxn[3]=max(maxn[3],dp[i]-que[i].x-que[i].y);
}
for(int i=1;i<=num;i++)
ans=max(ans,dp[i]);
cout<<ans<<endl;
return 0;
}

rp++

[CSP-S模拟测试]:biology(DP)的更多相关文章

  1. noi2019模拟测试赛(四十七)

    noi2019模拟测试赛(四十七) T1与运算(and) 题意: ​ 给你一个序列\(a_i\),定义\(f_i=a_1\&a_2\&\cdots\&a_i\),求这个序列的所 ...

  2. [考试反思]1109csp-s模拟测试106:撞词

    (撞哈希了用了模拟测试28的词,所以这次就叫撞词吧) 蓝色的0... 蓝色的0... 都该联赛了还能CE呢... 考试结束前15分钟左右,期望得分300 然后对拍发现T2伪了写了一个能拿90分的垃圾随 ...

  3. [考试反思]1003csp-s模拟测试58:沉淀

    稳住阵脚. 还可以. 至少想拿到的分都拿到了,最后一题的确因为不会按秩合并和线段树分治而想不出来. 对拍了,暴力都拍了.挺稳的. 但是其实也有波折,险些被卡内存. 如果内存使用不连续或申请的内存全部使 ...

  4. [考试反思]0814NOIP模拟测试21

    前两名是外校的240.220.kx和skyh拿到了190的[暴力打满]的好成绩. 我第5是170分,然而160分就是第19了. 在前一晚上刚刚爆炸完毕后,心态格外平稳. 想想前一天晚上的挣扎: 啊啊啊 ...

  5. csp-s模拟测试98

    csp-s模拟测试98 $T1$??不是我吹我轻松手玩20*20.$T2$装鸭好像挺可做?$T3$性质数据挺多提示很明显? $One$ $Hour$ $Later$ 这$T1$什么傻逼题真$jb$难调 ...

  6. csp-s模拟测试97

    csp-s模拟测试97 猿型毕露.水题一眼秒,火题切不动,还是太菜了. $T1$看了一会儿感觉$woc$期望题$T1??$假的吧??. $T2$秒. $T3$什么玩意儿. 40 01:24:46 00 ...

  7. csp-s模拟测试95

    csp-s模拟测试95 去世场祭. $T1$:这不裸的除法分块吗. $T2$:这不裸的数据结构优化$Dp$吗. $T3$:这不裸的我什么都不会搜索骗$30$分吗. 几分钟后. 这除法分块太劲了..(你 ...

  8. csp-s模拟测试93

    csp-s模拟测试93 自闭场. $T1$想到$CDQ$,因为复杂度少看见一个$0$打了半年还用了$sort$直接废掉,$T2$,$T3$直接自闭暴力分都没有.考场太慌了,心态不好. 02:07:34 ...

  9. csp-s模拟测试92

    csp-s模拟测试92 关于$T1$:最短路这一定建边最短路. 关于$T2$:傻逼$Dp$这一定线段树优化$Dp$. 关于$T3$:最小生成树+树P+换跟一定是这样. 深入(?)思考$T1$:我是傻逼 ...

随机推荐

  1. Logistic Algorithm分类算法的Octave仿真

    本次Octave仿真解决的问题是,根据两门入学考试的成绩来决定学生是否被录取,我们学习的训练集是包含100名学生成绩及其录取结果的数据,需要设计算法来学习该数据集,并且对新给出的学生成绩进行录取结果预 ...

  2. servlet--获取类路径下资源

     context 获取真实路径(*****) 还可以使用ServletContext对象来获取Web应用下的资源,例如在hello应用的根目录下创建a.txt文件,现在想在Servlet中获取这个资源 ...

  3. servlet--context域

    ServletContext(重要) 一个项目只有一个ServletContext对象! 我们可以在N多个Servlet中来获取这个唯一的对象,使用它可以给多个Servlet传递数据! 与天地同寿!! ...

  4. [Linux] 005 Linux 常见目录的作用及一些注意事项

    1. Linux 常见目录及其作用 目录名 作用 /bin/ 存放系统命令的目录普通用户各超级用户都可以执行放在 /bin 下的命令在单用户模式下也可以执行 /sbin/ 保存和系统环境相关的命令只有 ...

  5. kvm 修改虚拟机密码

    kvm 修改虚拟机密码 现在虚拟机kvm的使用很流行,为了更多的差异化环境,每个人可能拥有很多的kvm,这数量一多难免会有image的密码会忘记,相信很多人会采用kernel single user ...

  6. 2、NumPy 数据类型

    1.NumPy 数据类型 numpy 支持的数据类型比 Python 内置的类型要多很多,基本上可以和 C 语言的数据类型对应上,其中部分类型对应为 Python 内置的类型.下表列举了常用 NumP ...

  7. asp.net ajax的使用

    参考:https://www.cnblogs.com/acles/articles/2385648.html https://www.cnblogs.com/xujingyang/p/5560646. ...

  8. RabbitMQ ——简单队列

    一 .概述 我们不从开始就讲述基本的概念,尤其是在Rabbitmq之中有些概念确实比较难以理解,我们首先做的就是将光放提供的消息模型 进行实现,然后再总结一下Rabbitmq之中的基本概念. 二 .基 ...

  9. ssh-add - 向认证代理添加 RSA 或 DSA 身份数据

    总览 (SYNOPSIS) ssh-add [-lLdDx ] [-t life ] [file ... ] ssh-add -s reader ssh-add -e reader 描述 (DESCR ...

  10. BJSV-P-003高清智能卡口系统

    高清智能卡口系统 捕获率99%,车牌识别率98%   ■ 道路安装示意图 ■ 系统结构 ■      抓拍实例 北京太速科技有限公司在线客服:QQ:448468544 淘宝网站:orihard.tao ...