原题链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1083

题目分析:通过读题发现我们只能往右边或者下边走,意味着“不走回头路”,就是说矩阵里面每个位置最多只会经过一次。其实很多地方是“没有机会”经过的。比如我现在在第  行的第  列,不管之前走的路径是什么样子,则它左边和上边的位置都是不可能再走到的。也就是说,我先在在矩阵第  行的第  列,并假设以它为原点把矩阵分成四个“象限”,只有第四象限的位置才有可能从这以后经过 (当然还包括横轴的正半轴)!

假设我们从起点走到终点的过程中经过第  行的第  列某个位置,为了从起点到终点得到的和最大,那么从起点到第  行的第  列这个位置经过的数的和也一定要最大。我们定义集合  是从起点到第  行的第  列的全部路径集合,定义集合  是从第  行的第  列到终点的全部路径集合。那么起点到终点的路径实际上是子路径  和子路径 的连接(注意删掉第  行的第  列这个点,否则走了两次了)。 即所有经过第  行的第  列的路径都可以划分到  和 这两个集合里,而且任何  和子路径 都可以拼接出一条经过第  行的第  列的路径。那么我要选择一条经过  的能得到最大值的路径,显然要选择  集合里路径和最大的 ,(其实还要选  集合里和路径和最大的 )。

说了这么多,其实就是想明确一个事:从起点到终点的最优路径上经过了  个点,则这条路径上对应起点到这  个点的子路径也都从起点到该位置的所有路径中和最大的路径。

那么假设我们定义  表示从起点到第  行的第  列的最优路径上的数之和,并假设这个矩阵事个二维数组  (下标从  开始)。我们考虑一下,我们如何才能到 ?前一步要么到 , 要么到  ,因为有且只有这两个位置能到 ,那么怎样才能得到  ? 按我们前面说的,如果从起点达到  的最优路径要经过 或者 则,从起点到达  或者  的路径一定也必须是最优的。那么按照我们对  的定义,我们有从起点达到  的最优路径有两种可能:

  • 要么 
  • 要么 

我们要取最优,那自然取较大的,因此有  。这样原来要枚举指数条路径,现在对于每个位置只有两种情况啦。有了递推关系还不够,有初值才能求解。那我们看一下,显然这是在起点,没的选。那么按照递推式  , 但是我们对 没有定义呀!考虑下实际意义,这表示要么我们从上面到达  ,要么从左面到达 。可是上面没有位置过来啊,这种说明没的选。所以我们可以定义, 同理我们也可以定义

那么总结一下我们的递推式:


分析一下这个算法的时间复杂度? 显然是 ,空间复杂度也一样。


代码如下:

#include <iostream>
#include <algorithm>
using namespace std; const int INFTY = (1 << 29); int main() {
int n, a[505][505], dp[505][505];
cin >> n; for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cin >> a[i][j]; for (int i = 0; i <= n; i++) {
a[0][i] = INFTY;
a[i][0] = INFTY;
} for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i == 1 && j == 1 ) dp[i][j] = a[1][1];
else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + a[i][j];
}
} cout << dp[n][n] << endl; return 0;
}

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

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

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

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

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

  3. 1083 矩阵取数问题(DP)

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

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

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

  5. 51nod 1083 矩阵取数问题

    就很简单很简单的dp 只能从右或者从下走 所以  dp方程直接看下面公式吧  反正也不难 #include<bits/stdc++.h> using namespace std; ; in ...

  6. 51nod 更难的矩阵取数问题(动态规划)

    更难的矩阵取数问题 给定一个m行n列的矩阵,矩阵每个元素是一个正整数,你现在 在左上角(第一行第一列),你需要走到右下角(第m行,第n列),每次只能朝右或者下走到相邻的位置,不能走出矩阵.然后再从右下 ...

  7. 1166 矩阵取数游戏[区间dp+高精度]

    1166 矩阵取数游戏 2007年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description [ ...

  8. 矩阵取数游戏 NOIP 2007

    2016-05-31 17:26:45 题目链接: NOIP 2007 矩阵取数游戏(Codevs) 题目大意: 给定一个矩阵,每次在每一行的行首或者行尾取一个数乘上2^次数,求取完最多获得的分数 解 ...

  9. NOIP2007 矩阵取数游戏

    题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下: 1.每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. ...

随机推荐

  1. vue+element项目中动态表格合并

    需求:elementui里的table虽然有合并函数(:span-method),单基本都是设置固定值合并.现在有一个树型结构的数据,要求我们将里面的某个list和其他属性一起展开展示,并且list中 ...

  2. 08 - Vue3 UI Framework - Input 组件

    接下来再做一个常用的组件 - input 组件 返回阅读列表点击 这里 需求分析 开始之前我们先做一个简单的需求分析 input 组件有两种类型,即 input 和 textarea 类型 当类型为 ...

  3. linux小应用 —— 日志过滤

    先说问题,统计一个日志文件中去重之后的ip地址的个数.其实这是一个非常常见也比较简单的问题,其中我个人认为最主要的应该是匹配ip地址是这个问题的核心.剩下的就是对linux命令的熟练程度的问题了.首先 ...

  4. Android系统编程入门系列之硬件交互——多媒体展示

    前两篇文章通过麦克风硬件和摄像头硬件分别采集音频和视频的多媒体数据,在得到的多媒体数据通常是以编码文件的格式存储,在用户需要展示时,可通过设备的内置扩音器或蓝牙耳机等硬件播放音频,通过设备的显示屏或外 ...

  5. [BUUCTF]PWN——roarctf_2019_easy_pwn(详解)

    roarctf_2019_easy_pwn 附件 步骤: 例行检查,64位程序,保护全开 试运行一下程序,看看大概的情况,经典的堆块的菜单 64位ida载入,改了一下各个选项的函数名,方便看程序(按N ...

  6. css实现hover显示下拉菜单

    原理比较简单,首先先隐藏下拉菜单即display:none,当鼠标hover后,设置display:block. <style> .menu-title { postion: relati ...

  7. SpringBoot 整合es(elasticsearch)使用elasticsearch-rest-high-level-client实现增删改

    引入依赖 <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok< ...

  8. JS设置网站所有字体变为繁体字

    引入chinese.js var zh_default='n';var zh_choose='t';var zh_expires=7;var zh_class='zh_click';var zh_st ...

  9. JAVAWEB使用保存cookie、删除cookie、获取cookie工具类

    package com.test; import org.apache.commons.lang.StringUtils; import org.springframework.util.Assert ...

  10. linux 设备文件的操作

    文件:包含数据,具有属性,通过目录中的名字被标识, 可以从文件读数据,可以向文件写数据. 设备也支持文件的操作. 每个设备都被当作一个文件,具有文件名,i-节点号,文件所有者,权限位的集合,最新修改时 ...