1. 程式人生 > >從矩陣左上角至右下角(無權值)問題

從矩陣左上角至右下角(無權值)問題

問題來源

來自於Euler Project的第十五個題目,題目不復雜,但是可以有很多種思路和解法。此外,我宿舍一姐們面試剛好碰到此題。題目連結

問題描述

一個 M*N 的矩陣,從矩陣的左上角到矩陣的右下角,只能向右走或者向下走,有多少種解法?

例如一個2*2的矩陣,有下面六種解法。


問題解法

假設矩陣有M行N列。

1、數學解法

使用排列組合有兩種思路。因為只能向右走或者向下走。

(1)在M+N次行走後,才能到達終點,也就是右下角,而在這M+N次行走中,有M次是向下,N次向右。所以是一個選擇問題。


對於Euler這題而言,就是C(40, 20),在google中輸入40 choose 20,答案就出來啦。


(2)水平行走記作0,豎直行走記作1。每一種行走足跡可以作為一個0,1串,其中n個0,m個1。可以看做0000000000000(n個0)1111111111111(m個1)的重排列。

也就是


如果實在想不出公式,可以寫出前面一些特殊的然後找規律,這也是沒有辦法的辦法了,但是不一定有效。

2、遞迴解法。

遞迴,動態規劃,說白了,就是把一個問題分解成子問題,然後找出最小子問題。動態規劃還需要找出問題的求解順序。

因此,我們發現了這個問題的遞迴式:

matrix[i][j]=matrix[i-1][j] + matrix[i][j-1]

以及初始條件:matrix[i][0]=matrix[0][j]=1

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
__int64 digui(int row, int col){
        if(row == 1 || col == 1) return 1;
        else return digui(row-1, col) + digui(row, col-1);
}
int main(){
    clock_t begin = clock();
    printf("%lld\n", digui(18,18));
    clock_t end = clock();
    double cost = (double)(end - begin) / CLOCKS_PER_SEC;
    printf("%lf seconds\n", cost);
    system("pause");
}

但是,遞迴因為不記錄中間結果,會重複計算很多中間值,超級費時!

比如這個程式在我的PC上跑,16*16的時候,需要3.727000秒。而17*17規模,需要13.601000秒,當問題規模到18*18時候計算時間已經到了52.803000秒了,基本到21*21是很慢很慢的了。

3、動態規劃解法

和遞迴的原理差不多,需要多注意一個問題就是計算順序的問題。這個題就按順序一行一行掃描就行了。

#include<stdio.h>
#define XMAX 21
#define YMAX 21
int main() {
  __int64 matrix[XMAX][YMAX];
  for(int i=0;i<XMAX;i++) matrix[i][0]=1;
  for(int i=0;i<YMAX;i++) matrix[0][i]=1;
  for(int i=1;i<XMAX;i++) 
    for(int j=1;j<YMAX;j++)
      matrix[i][j]=matrix[i-1][j]+matrix[i][j-1];
  printf("%lld",matrix[20][20]);
}

相關推薦

矩陣左上角右下無權問題

問題來源 來自於Euler Project的第十五個題目,題目不復雜,但是可以有很多種思路和解法。此外,我宿舍一姐們面試剛好碰到此題。題目連結 問題描述 一個 M*N 的矩陣,從矩陣的左上角到矩陣的右下角,只能向右走或者向下走,有多少種解法? 例如一個2*2的矩陣,有下面六

python實現二維矩陣左上角右下的出路數尋找

   問題:     給定一個二微矩陣,從左上角出發到右下角,每一次只能往下和往右走,求一共有多少種走法     具體實現如下: #!usr/bin/env python #encoding:utf-8 ''' __Author__:沂水寒城 功能:在二維矩陣中向下和向

8*8矩陣左上角右下一共有多少種走法

8*8矩陣,只能向右或者向下,從左上角到右下角一共有多少種走法,並且只能在對角線的右上行走,可在對角線上行走。 public class Main{ public static void main(String[] args) { int ans = 0; in

方格左上角右下的走法

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The robot can only move either

矩陣左上角右下最短路徑五種方法

題目:給定一個n*m的矩陣,矩陣中元素非負,從左上角到右下角找一條路徑,使得路徑上元素之和最小,每次只能向右或者向下走一個方格。如下圖所示:最短路徑是圖中綠色部分的元素。 方法一(轉換為圖中的最短路徑):我們可以把矩陣中的每個方格當做圖中的一個頂點,相鄰的方格之間

3. Project Euler15 給定一個20*20的方格,左上角右下的路徑有多少條?只允許向右和向下走)

【微--策--略】 1. 五個洞排成一排,其中一個洞裡藏有一隻狐狸。每個夜晚,狐狸都會跳到一個相鄰的洞裡;每個白天,你都只允許檢查其中一個洞。怎樣才能保證狐狸最終會被抓住? 解答:有個問題 錯了 下面是少一天的推理 第一天2洞 第二天2洞 都沒有的話 證明它在後三個裡面 第三天4洞 第四天4

m*n矩陣左上角右下的路徑最小和

package leetcode; /*Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right  which minimizes the sum of al

【DP】在矩陣中,選擇一條左上角右下、經過數字之和最大的路徑

題目:EPI int max_fishing(vector<vector<int>> A) { if (A.empty() || A[0].empty()) throw new exception; for (int i = 0; i &l

矩陣左上角右下的最優路徑使得經過路徑上的權和最大(最小)

描述: 有一張藏寶圖,而藏寶圖描述的所在區域(只有一個左上角入口和一個右下角出口)被分為m*n的小區域,並且每一個小區域內都藏有一定數量N(0<=N<=9)的寶貝,但要求只能從當前位置向右邊或者下邊尋找寶貝。如果你非常幸運,得到了這張藏寶圖

矩陣左上角右下的路徑條數

題目:給定一個n*m矩陣,求從左上角到右下角總共存在多少條路徑,每次只能向右走或者向下走。 解法一:和上一篇文章的思想相似,在此不再重複敘述。int uniquePaths(int m, int n) { if (m <= 0 || n <= 0) re

經典面試題——矩陣左上角右下有多少種方法。

不多說,程式碼獻上,三種方法 #include <iostream> using namespace std; int mat[11][11]; int dp[11]; int main() { int n, m; int i, j; //樸素DP

動態規劃---左上角右下的價值最大的路徑

一個 view algorithm sin sum ack for track cout 編程題:動態規劃---從左上角到右下角的價值最大的路徑 騰訊2016年4月2號暑假實習移動開發崗的筆試題,編程題第一題大概題目是: 一個m*n的矩陣,只能向右走或是向下走,矩陣每

給出一個m*n的矩陣,求左上角右下的距離的最小

問題描述 這是一個商湯科技筆試題的變形,大致是給出一個m*n的矩陣,矩陣裡的數代表其他相鄰格到此格的距離,且只能向右和向下走,求左上角到右下角的距離的最小值。 例: 0 1 9 3 5 2 6 8 7 這個例子的最短距離是0-1-5-2-7,結果是15。 這個真

LeetCode 62. Unique Paths--二維陣列左上角右下的唯一路徑的種數有多少,只能向右或向下移動--DP

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The robot can only move either down or r

程式設計題:動態規劃---左上角右下的價值最大的路徑

騰訊2016年4月2號暑假實習移動開發崗的筆試題,程式設計題第一題大概題目是: 一個m*n的矩陣,只能向右走或是向下走,矩陣每一個元素代表一個財富值,要求打印出從左上角到右下角走的財富最大總值。

每天一道LeetCode-----計算二維陣列的左上角到達右下的所有路徑數及最短的那條,如果存在障礙物時又是多少

Unique Paths 原題連結Unique Paths 計算從左上角有多少條不同的路徑可以到達右下角,移動方向只能是向右和向下。 對於每個位置,都有兩種移動的可能,即向右移動和向下移動。可以用深度優先(dfs)解決,同時為了解決重複計算,可以用動態

[leetcode 64] Minimum Path Sum------左上角右下的最小路徑

Question: Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all

n乘n的方框左上角右下有多少種走法

從最上角到最下角橫向走的“步數”應該是n-1步,而豎向走的“步數”也是n-1步,所以從左上角到右下角必須走2n-2步。 接著,在總共2n-2步中,選擇n-1步作為橫向,則另外n-1步應該為豎向,由排列組合有:cn-12n-2 可實現的程式碼如下: #include &

打印九九乘法表,左下角、右上角、左上角右下

格式 最簡 列數 右上角 int() 空白 右下角 else 部分 左下角 # 這種情況最簡單,列數<=行數,從左邊打印即可 for i in range(1, 10): for j in range(1, 10): if j <= i:

最小化後右下托盤小圖示的實現

1.想要實現這樣的效果 2.我參考了“如何實現最小化後出現右下角圖示”http://www.cnblogs.com/weiqubo/archive/2010/12/25/1917013.html   "讓一個程式托盤顯示,並且右鍵托盤圖示可以彈出選單"http://www.