資源限制
時間限制: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 21 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 個格仔的矩陣。每個格仔放一件寶貝。每個寶貝貼著價值標籤。地宮的入口在左上角,出口在右下角。小明被帶到地宮的入口,國王要求他只能向右或向下行走。走過某個格仔時,如果那個格仔中的寶貝價值比小明手中任意寶貝價值都大,小明就可以拿起它 當然,也可以不拿 當小明走到出口...