藍橋杯 歷屆試題 地宮取寶

2021-10-07 02:14:53 字數 1975 閱讀 1994

資源限制

時間限制:1.0s 記憶體限制:256.0mb

問題描述

x國王有乙個地宮寶庫。是n x m 個格仔的矩陣。每個格仔放一件寶貝。每個寶貝貼著價值標籤。

地宮的入口在左上角,出口在右下角。

小明被帶到地宮的入口,國王要求他只能向右或向下行走。

走過某個格仔時,如果那個格仔中的寶貝價值比小明手中任意寶貝價值都大,小明就可以拿起它(當然,也可以不拿)。

當小明走到出口時,如果他手中的寶貝恰好是k件,則這些寶貝就可以送給小明。

請你幫小明算一算,在給定的局面下,他有多少種不同的行動方案能獲得這k件寶貝。

輸入格式  

輸入一行3個整數,用空格分開:n m k (1<=n,m<=50, 1<=k<=12)

接下來有 n 行資料,每行有 m 個整數 ci (0<=ci<=12)代表這個格仔上的寶物的價值

輸出格式

要求輸出乙個整數,表示正好取k個寶貝的行動方案數。該數字可能很大,輸出它對 1000000007 取模的結果。

2 2 2

1 22 1

2 3 2

1 2 3

2 1 5

參考思路

1、依照題意,小明每走一步都與之前的舉動有關,我們要做的就是一直往下走,走不通了就掉頭,換一條路再往下走,可以很自然的想到使用深搜。

2、僅僅使用深度搜尋的方法時存在大量重複計算,並且結果超時,因此需要使用陣列儲存路徑值,重複遍歷時直接傳值。根據題意,每個格仔的值與格仔橫縱座標,最大價值及獲得寶貝數有關,因此用乙個四維陣列來表示。

3、根據題意,列出其狀態轉移方程:

其中i,j表示格仔位置,k表示該格仔獲得了k件寶貝,v表示此時經過路徑中,最大值為v。初始情況下k=0,v=-1(v值取值範圍為0~12,為了加以區分)。d(i,j,k,v)表示從原點開始達到第(i,j)點,手握k件寶物並且最大價值為v時可以走的路徑。

註解:當小明剛到達(i,j)時會面臨兩種情況,第一,此格寶物價值高於當前最**值,小明可以選擇撿或不撿;第二,此格寶物價值不高於當前價值,小明不能撿。

同時小明下一步可能走的地點為(i+1,j)或者(i,j+1),因此小明到達下一格時會有6種情況。

反過來說,小明在(i,j)所可能的路徑即為這六種情況的路徑之和。

4、在遍歷的眾多過程中,可能存在有一種或多種方式不能得到符合要求的答案,也就是d(i,j,k,v)=0,因此為了區分,初始值設為d=-1。

5、寶物價值初始值設為了-1,為了防止越界,對其下標後移一位。

6、遞迴至最後一步開始時,符合要求的情況有兩種:

第一、此時已有k件寶物;

第二、此時已有k-1件寶物,且最後乙個方格的寶物價值大於已擁有的最大值。

ps:該答案可能很大,在取模的同時選擇long long更加穩妥。

#include

#include

using

namespace std;

#define mod %1000000007

int n,m,num;

int map[60]

[60];

int d[60]

[60][

13][13

];long

long

dfs(

long

long i,

long

long j,

long

long k,

long

long v)

else

else

d[i]

[j][k]

[v+1

]=s;

return d[i]

[j][k]

[v+1];

}}intmain()

藍橋杯 歷屆試題 地宮取寶

我本來想dp的 可惜dp不出來 後來才知道是記憶化搜尋 至於那個返回的max 1是因為 本來返回max 的 但是因為一開始代入dfs的引數是 1 所以就要 1 include include const int mod 1000000007 int a 51 51 int dp 51 51 13 1...

藍橋杯 歷屆試題 地宮取寶

問題描述 x 國王有乙個地宮寶庫。是 n x m 個格仔的矩陣。每個格仔放一件寶貝。每個寶貝貼著價值標籤。地宮的入口在左上角,出口在右下角。小明被帶到地宮的入口,國王要求他只能向右或向下行走。走過某個格仔時,如果那個格仔中的寶貝價值比小明手中任意寶貝價值都大,小明就可以拿起它 當然,也可以不拿 當小...

藍橋杯 歷屆試題 地宮取寶

x 國王有乙個地宮寶庫。是 n x m 個格仔的矩陣。每個格仔放一件寶貝。每個寶貝貼著價值標籤。地宮的入口在左上角,出口在右下角。小明被帶到地宮的入口,國王要求他只能向右或向下行走。走過某個格仔時,如果那個格仔中的寶貝價值比小明手中任意寶貝價值都大,小明就可以拿起它 當然,也可以不拿 當小明走到出口...