基准时间限制: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. 启动关闭zookeeper集群的脚本

    启动hadoop Ha集群是,每次都要手动启动每个zk节点,实在是太麻烦了.于是乎自己写了个脚本startAllZK.sh: 需要启动的节点,先在 NODENAME_ARR 数组中配置好,zkServ ...

  2. 一个比较实用的商业级图表Echarts

      了解了解                    ECharts,缩写来自Enterprise Charts,商业级数据图表,一个纯Javascript的图表库,可以流畅的运行在PC和移动设备上,兼 ...

  3. Windows环境下Android Studio安装和使用教程

    Windows环境下Android Studio安装和使用教程 来源: http://www.cnblogs.com/liuhongfeng/archive/2015/12/30/5084896.ht ...

  4. linq 在查询表达式中处理异常

    在查询表达式的上下文中可以调用任何方法. 但是,我们建议避免在查询表达式中调用任何会产生副作用(如修改数据源内容或引发异常)的方法. 此示例演示在查询表达式中调用方法时如何避免引发异常,而不违反有关异 ...

  5. Clipboard 剪辑板

    ie是最早支持剪辑板相关事件(并且允许javascript接入)的浏览器(鼠标右键复制)   相关事件: beforecopy— Fires just before the copy operatio ...

  6. JAVA提高十二:HashMap深入分析

    首先想说的是关于HashMap源码的分析园子里面应该有很多,并且都是分析得很不错的文章,但是我还是想写出自己的学习总结,以便加深自己的理解,因此就有了此文,另外因为小孩过来了,因此更新速度可能放缓了, ...

  7. mysql +keeplive

    下载tar包 ./configure --prefix=/usr/local/keepalived --with-kernel-dir=/usr/src/kernels/2.6.32-431.el6. ...

  8. javaScript函数提升及作用域

    代码片段: var a = 1; function foo() { console.log(a); //输出为undefined if (!a) { var a = 2; } alert(a); }; ...

  9. 八:Lombok 安装、入门 - 消除冗长的 java 代码

    Lombok 安装.入门 - 消除冗长的 java 代码 前言:    逛开源社区的时候无意发现的,用了一段时间,觉得还可以,特此推荐一下.    lombok 提供了简单的注解的形式来帮助我们简化消 ...

  10. C# 4.0 新特性dynamic、可选参数、命名参数等

    1.dynamic ExpandoObject熟悉js的朋友都知道js可以这么写 :   1 var t = new Object(); 2 t.Abc = ‘something’; 3 t.Valu ...