基准时间限制:2 秒 空间限制:131072 KB 
一个M*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,先从左上走到右下,再从右下走到左上。第1遍时只能向下和向右走,第2遍时只能向上和向左走。两次如果经过同一个格子,则该格子的奖励只计算一次,求能够获得的最大价值。

 
例如:3 * 3的方格。
 
1 3 3
2 1 3
2 2 1
 
能够获得的最大价值为:17。1 -> 3 -> 3 -> 3 -> 1 -> 2 -> 2 -> 2 -> 1。其中起点和终点的奖励只计算1次。
 
Input
第1行:2个数M N,中间用空格分隔,为矩阵的大小。(2 <= M, N <= 200)
第2 - N + 1行:每行M个数,中间用空格隔开,对应格子中奖励的价值。(1 <= A[i,j] <= 10000)
Output
输出能够获得的最大价值。
Input示例
3 3
1 3 3
2 1 3
2 2 1
Output示例
17

思路:双线DP,看成两个人一起从(1,1)到(N,M),走的路径不能相同。

方法1:按照路径长度考虑,路径总长度:tot=x+y-1,dp[tot][x1][x2],两个人的横坐标x1,x2

 #include <bits/stdc++.h>
using namespace std;
int ans[][],dp[][][];
int main() {
int M,N;
scanf("%d %d",&M,&N);
for(int i=;i<=N;++i)
for(int j=;j<=M;++j)
scanf("%d",&ans[i][j]);
memset(dp,,sizeof(dp));
for(int tot=;tot<=N+M-;++tot)//路径长度
for(int i=;i<=N&&(<=tot+-i);++i)
for(int j=;j<=N&&(<=tot+-j);++j) {
dp[tot][i][j]=max(dp[tot][i][j],dp[tot-][i-][j-]);
dp[tot][i][j]=max(dp[tot][i][j],dp[tot-][i-][j]);
dp[tot][i][j]=max(dp[tot][i][j],dp[tot-][i][j-]);
dp[tot][i][j]=max(dp[tot][i][j],dp[tot-][i][j])+ans[i][tot+-i]+ans[j][tot+-j];
if(i==j) dp[tot][i][j]-=ans[i][tot+-i];
}
printf("%d\n",dp[N+M-][N][N]);
return ;
}

方法2:按照走到走了几步,总的步数:tot=x+y-2

 #include <bits/stdc++.h>
using namespace std;
int ans[][],dp[][][];
int main() {
int M,N;
scanf("%d %d",&M,&N);
for(int i=;i<=N;++i)
for(int j=;j<=M;++j)
scanf("%d",&ans[i][j]);
memset(dp,,sizeof(dp));
dp[][][]=ans[][];//一步都没走
for(int tot=;tot<=N+M-;++tot)//走了几步
for(int i=;i<=N&&(i-<=tot);++i)
for(int j=;j<=N&&(j-<=tot);++j) {
dp[tot][i][j]=max(dp[tot][i][j],dp[tot-][i-][j-]);
dp[tot][i][j]=max(dp[tot][i][j],dp[tot-][i-][j]);
dp[tot][i][j]=max(dp[tot][i][j],dp[tot-][i][j-]);
dp[tot][i][j]=max(dp[tot][i][j],dp[tot-][i][j])+ans[i][tot+-i]+ans[j][tot+-j];
if(i==j) dp[tot][i][j]-=ans[i][tot+-i];
}
printf("%d\n",dp[N+M-][N][N]);
return ;
}

方法3:对方法2的优化,滚动数组

 #include <stdio.h>
#include <string.h>
int ans[][],dp[][][];
int max(int a, int b) {if(a>=b) return a;return b;}
int main() {
int M,N;
scanf("%d %d",&M,&N);
for(int i=;i<=N;++i)
for(int j=;j<=M;++j)
scanf("%d",&ans[i][j]);
memset(dp,,sizeof(dp));
dp[][][]=ans[][];//一步都没走
int dir=;
//tot->走了几步
for(int tot=;tot<=N+M-;++tot) {
dir=-dir;
for(int i=;i<=N&&(i-<=tot);++i)
for(int j=;j<=N&&(j-<=tot);++j) {
dp[dir][i][j]=max(dp[dir][i][j],dp[-dir][i-][j-]);
dp[dir][i][j]=max(dp[dir][i][j],dp[-dir][i-][j]);
dp[dir][i][j]=max(dp[dir][i][j],dp[-dir][i][j-]);
dp[dir][i][j]=max(dp[dir][i][j],dp[-dir][i][j])+ans[i][tot+-i]+ans[j][tot+-j];
if(i==j) dp[dir][i][j]-=ans[i][tot+-i];
}
}
printf("%d\n",dp[dir][N][N]);
return ;
}

51Nod 1084 矩阵取数问题 V2 双线程DP 滚动数组优化的更多相关文章

  1. 51Nod 1084 矩阵取数问题 V2 —— 最小费用最大流 or 多线程DP

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1084 1084 矩阵取数问题 V2  基准时间限制:2 秒 空 ...

  2. 1084 矩阵取数问题 V2

    1084 矩阵取数问题 V2 基准时间限制:2 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 一个M*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,先从左上走到右下 ...

  3. 51Nod 1084:矩阵取数问题 V2(多维DP)

    1084 矩阵取数问题 V2  基准时间限制:2 秒 空间限制:131072 KB 分值: 80 难度:5级算法题  收藏  关注 一个M*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励 ...

  4. 51nod1084 矩阵取数问题 V2

    O(n4)->O(n3)妈呀为什么跑这么慢woc #include<cstdio> #include<cstring> #include<cctype> #i ...

  5. 51Nod 1083 矩阵取数问题(矩阵取数dp,基础题)

    1083 矩阵取数问题 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 一个N*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,从左上走到右下,只能向下 ...

  6. [Swust OJ 1084]--Mzx0821月赛系列之情书(双线程dp)

    题目链接:http://acm.swust.edu.cn/problem/1084/ Time limit(ms): 1000 Memory limit(kb): 65535   Descriptio ...

  7. 51nod 1411 矩阵取数问题 V3

    给定一个m行n列的矩阵,你可以从任意位置开始取数,到达任意位置都可以结束,每次可以走到的数是当前这个数上下左右的邻居之一,唯一的限制是每个位置只能经过一次,也就是说你的路径不自交.所经过的数的总作为你 ...

  8. 51nod动态规划-----矩阵取数

    一个N*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,从左上走到右下,只能向下向右走,求能够获得的最大价值. 例如:3 * 3的方格. 1 3 3 2 1 3 2 2 1 能够获得的最 ...

  9. 51nod 1083 矩阵取数问题【动态规划】

    一个N*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,从左上走到右下,只能向下向右走,求能够获得的最大价值. 例如:3 * 3的方格. 1 3 3 2 1 3 2 2 1 能够获得的最 ...

随机推荐

  1. Ubuntu on win10

    大家看到这个题目应该都知道这个东西吧,或许也都知道咋安装啥的,我只是想分享一下自己安装它的过程同时可以对那些有需要的人给予帮助!!! 1. 打开开发者模式(如下图) 像上面这样打开开发人员模式,过程会 ...

  2. idea配置jetty服务器,通过mvn实现

    今天想试试除了tomcat之外的另一个服务器jetty的使用: 关于项目在tomcat中的启动大概有多种,尤其是在本地环境下,ide关于tomcat的优化做的很好,但是在idea上面部署tomcat总 ...

  3. web消息推送-goesay

    原文:http://www.upwqy.com/details/22.html 1 GoEasy简介: GoEasy - Web实时消息推送服务专家 最简单的方式将消息从服务器端推送至客户端 最简单的 ...

  4. Just a Hook(区间set)

    Just a Hook Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  5. eclipse运行中出错:unknown protocol: hdfs

    出现这个错误因为你没有把core-site.xml和hdfs-site.xml放到项目下 程序运行开始就要调用这两个配置文件,这两个文件就是配置Hadoop时候的配置文件,只需要把至两个文件copy到 ...

  6. 五种js判断是否为整数(转)

    五种js判断是否为整数类型方式 作者:snandy 这篇文章主要介绍了五种JavaScript判断是否为整数类型方式,需要的朋友可以参考下   这篇看看如何判断为整数类型(Integer),JavaS ...

  7. 「设计模式」JavaScript - 设计模式之单例模式与场景实践

    单例介绍 上次总结了设计模式中的module模式,可能没有真真正正的使用在场景中,发现效果并不好,想要使用起来却不那么得心应手, 所以这次我打算换一种方式~~从简单的场景中来看单例模式, 因为Java ...

  8. Mysql修改已有数据的字符集

    Mysql修改已有数据的字符集 问题 在生产环境中跑了很久,发现MysqlClient连接的字符集是默认的latin1,我们一直以为都是utf8,造成这样的误解,是因为在内网环境中,我们是源码编译的M ...

  9. Java多线程Master-Worker模式

    Java多线程Master-Worker模式,多适用于需要大量重复工作的场景中. 例如:使用Master-Worker计算0到100所有数字的立方的和 1.Master接收到100个任务,每个任务需要 ...

  10. 使用Docker运行Microsoft SQL Server 2017

    最近每天都在空闲时间努力编写Apworks框架的案例代码WeText.在文本发布和处理微服务中,我打算使用微软的SQL Server for Linux来做演示,于是也就在自己的docker-comp ...