更难的矩阵取数问题

给定一个m行n列的矩阵,矩阵每个元素是一个正整数,你现在 在左上角(第一行第一列),你需要走到右下角(第m行,第n列),每次只能朝右或者下走到相邻的位置,不能走出矩阵。然后再从右下角返回到左上角,这时只 能朝上或者左走,两次如果经过同一个格子,则该数字只计算一次,所有走过的数的总和作为你的得分,求最大的得分。

 
输入

第1行:2个数M N,中间用空格分隔,为矩阵的大小。(2 <= M, N <= 200)
第2 - N + 1行:每行M个数,中间用空格隔开,对应格子中奖励的价值。(1 <= A[i,j] <= 10000)
输出
输出能够获得的最大价值。
输入示例

3 3
1 3 3
2 1 3
2 2 1
输出示例

17
请选取你熟悉的语言,并在下面的代码框中完成你的程序,注意数据范围,最终结果会造成Int32溢出,这样会输出错误的答案。
不同语言如何处理输入输出,请查看下面的语言说明。
 
【分析】
 
没招了么?其实我们可以“两个人一起”dp(让两个人同时走)。

用dp[x1][y1][x2][y2]表示第一个人在(x1,y1) 并且第二个人在(x2,y2)时的最大值。
我们有初值dp[1][1][1][1] = a[1][1], 求的是dp[m][n][m][n]。
问题来了: 每个人走一步,状态转移是什么?
dp[x1][y1][x2][y2] = max{dp[x1’][y1’][x2’][y2’]} + a[x1][y1] + a[x2][y2]
其中(x1’,y1’)是(x1,y1)的邻居,(x2’,y2’)是(x2,y2)的邻居。
事实上,因为我们有这个等式提示我们其实只要用3维就可以表示这个矩阵,因为 y2 = x1 + y1 – x2所以那一维可以用走多少步表示出来。
 
dp[step + 1][x1][x2] = max{dp[step][x1’][x2’]} + a[x1][y1] + a[x2][y2]
 
图中为step做了编号。
然而这个dp并没有体现出走到相同格子,数字仅计算一次的要求。那么我们加上这个条件:如果x1 = x2,dp[step + 1][x1][x2] = max{dp[step][x1’][x2’]} + a[x1][y1]。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <list>
#define inf 0x3f3f3f3f
typedef long long ll;
using namespace std ;
#define inf 0x3f3f3f3f
#define maxn 201
int M[maxn][maxn];
int dp[maxn<<][maxn][maxn];
int main()
{
int n,m,i,j,x1,x2;
scanf("%d%d",&m,&n);
for(i=;i<=n;++i)
for(j=;j<=m;++j)
scanf("%d",&M[i][j]);
memset(dp,,sizeof(dp)); for(i=;i<n+m;++i)
for(x1=;x1<=n&&i-x1>=;++x1)
for(x2=;x2<=n&&i-x2>=;++x2)
{ dp[i][x1][x2]=max(dp[i][x1][x2],dp[i-][x1-][x2-]+M[x1][i-x1+]+(x1==x2?:M[x2][i-x2+])); dp[i][x1][x2]=max(dp[i][x1][x2],dp[i-][x1-][x2]+M[x1][i-x1+]+(x1==x2?:M[x2][i-x2+])); dp[i][x1][x2]=max(dp[i][x1][x2],dp[i-][x1][x2-]+M[x1][i-x1+]+(x1==x2?:M[x2][i-x2+])); dp[i][x1][x2]=max(dp[i][x1][x2],dp[i-][x1][x2]+M[x1][i-x1+]+(x1==x2?:M[x2][i-x2+]));
//printf("dp[%d][%d][%d]=%d\n",i,x1,x2,dp[i][x1][x2]);
}
printf("%d\n",dp[n+m-][n][n]);
return ;
}

51nod 更难的矩阵取数问题(动态规划)的更多相关文章

  1. 51nod 更难的矩阵取数问题 + 滚动数组优化

    这里要求要走到终点再走回来,可以转化为两个人走. 那么我们可以先粗暴的设f[x1][y1][x2][y2]为第一个人走到(x1, y1), 第二个人走到(x2, y2)的最大价值. 那么这样空间会很大 ...

  2. [多路dp]更难的矩阵取数问题

    https://www.51nod.com/tutorial/course.html#!courseId=11&isCurrent=1 解题关键:1.注意i和j的最大取值都是n,k是i与j的和 ...

  3. 51Nod 1083 矩阵取数问题 | 动态规划

    #include "bits/stdc++.h" using namespace std; #define LL long long #define INF 0x3f3f3f3f3 ...

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

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

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

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

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

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

  7. 【NOIP2007】矩阵取数

    因为傻逼写错高精度搞了一下午浪费好多时间,好想哭qaq 原题: 帅帅经常更同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij据为非负整数.游戏规则如下: 1. 每次取数时须从每 ...

  8. P1005 矩阵取数游戏 区间dp 高精度

    题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n \times mn×m的矩阵,矩阵中的每个元素a_{i,j}ai,j​均为非负整数.游戏规则如下: 每次取数时须从每行各取走一个元素,共n ...

  9. 1084 矩阵取数问题 V2

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

随机推荐

  1. BZOJ1191:超级英雄(二分图匹配)

    [HNOI2006]超级英雄Hero 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1191 Description: 现在电视台有一种节 ...

  2. 原生toolbar基本使用教程

    1.先写布局文件 <android.support.v7.widget.Toolbar android:id="@+id/toolbar" app:title=" ...

  3. oracle的sql语句训练

    --查询工资最高的人的名字select ename ,sal from emp where sal=(select max(sal) from emp );--求出员工的工资在所有人的平均工资之上的人 ...

  4. bzoj 3720 Gty的妹子树 树分块?瞎搞

    Gty的妹子树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2149  Solved: 781[Submit][Status][Discuss] D ...

  5. 理解PHP链式调用

    php链式操作:类似如下实现 $db->where()->limit()->order(); 不使用链式调用时的代码格式如下: namespace Database; class D ...

  6. 串的模式匹配算法(求子串位置的定位函数Index(S,T,pos))

    串的模式匹配的一般方法如算法4.5(在bo4-1.cpp 中)所示:由主串S 的第pos 个字 符起,检验是否存在子串T.首先令i 等于 pos(i 为S 中当前待比较字符的位序),j 等于 1(j ...

  7. 转:使用 Nginx Upload Module 实现上传文件功能

    普通网站在实现文件上传功能的时候,一般是使用Python,Java等后端程序实现,比较麻烦.Nginx有一个Upload模块,可以非常简单的实现文件上传功能.此模块的原理是先把用户上传的文件保存到临时 ...

  8. 利用saltstack初始化OpenStack服务器环境

    目录架构图如上图所示 sls脚本详情如下: Sync_Host: file.managed: - name: /etc/hosts - source: salt://state/files/hosts ...

  9. bzoj4602 [Sdoi2016]齿轮

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4602 [题解] 对于每组齿轮(u, v)连边,权值为y/x(反向边x/y) 那么直接dfs计 ...

  10. NGINX: 配置跨域请求

    说明: 内容全部来自 SegmentFault Developer Nginx 配置跨域请求 跨域请求失败, nginx 报错: 403 No 'Access-Control-Allow-Origin ...