地宮取寶
時間限制: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樣例輸入
2 3 2
1 2 3
2 1 5
樣例輸出
14分享優質題解:
話說這個題目意圖還是蠻明顯的,深搜完後返回所有滿足的解的個數,不過這個善意的題目,要想完全正確還是學需要在處理時注意很多方面。
首先,先來談第乙個問題,寫出其狀態轉移方程,我們要求的解是從原點手握價值最大的寶物v開始經過不同的路徑到終點獲得k件寶物的路徑總數,我們姑且將此狀態記為
d(1,1,k(
初始為0
,還沒拿寶貝
),-1(
此時手上沒有寶物,值記為
-1))
那麼從此狀態出發,可以將其轉移為如下的決策
這裡在補充說明用狀態轉移方程可以方便將原問題分解成若干個與原問題相同的子問題,且規模變小。
第二個問題,如果僅僅這樣的話,必然存在重複計算的問題,為此必須要採取記憶化搜尋
的方式,對於已經計算過的結點儲存其值,就這條題目而言,必須要用乙個四維陣列儲存,因為它的狀態跟位置,個數以及當前最大的寶物價值有關。當重複遍歷這個結點時,直接傳值。
第三個問題,細節決定成敗!!
1.型別用long long穩妥,因為即使mod了,但是如果兩個數加起來還有可能超int。
2.我自己做的時候沒注意的乙個小錯誤,導致最後始終不對的疏忽。我錯誤的把r[maxn][maxn][15][15]的初始化為了0,這絕對不正確,因為有可能以某種方式走的狀態就是無解,就是0,必須將初始值賦為-1。
3.對於有寶物的初始價值為-1,比較好的處理方式是,最後存放是第四維的下標後移一位
4.這裡還要注意,k最多是13,不會超過這個值,所以第三維只要14就夠了
**:
#include#include#includeusing namespace std;
const int maxn = 60;
typedef long long ll;
#define mod 1000000007
ll dp[maxn][maxn][15][15];
ll mp[maxn][maxn];
ll n, m, num;
ll dfs(int i, int j, int k, int val)
else if(k == num - 1 && mp[n][m] > val)
else
}else
else
dp[i][j][k][val+1] = s % mod;
return dp[i][j][k][val+1];
}}int main()
return 0;
}
藍橋杯 地宮取寶 (DFS 記憶化搜尋)
歷屆試題 地宮取寶 時間限制 1.0s 記憶體限制 256.0mb 問題描述 x 國王有乙個地宮寶庫。是 n x m 個格仔的矩陣。每個格仔放一件寶貝。每個寶貝貼著價值標籤。地宮的入口在左上角,出口在右下角。小明被帶到地宮的入口,國王要求他只能向右或向下行走。走過某個格仔時,如果那個格仔中的寶貝價值...
藍橋杯 地宮取寶 (記憶化搜尋)
思路 記憶化搜尋,dp x y curmax num 記錄的是要取 x,y 位置時,拿了num個物品,其中最大價值為curmax的 時 候的方案數量。注意有個坑點,物品價值可能為0,搜尋時我們初始價值為0,但第乙個價值為0的物品是可以取的,所以我們讀入時 講 所有物品價值 1.include inc...
藍橋杯試題 地宮取寶 (記憶化搜尋)
歷屆試題 地宮取寶 時間限制 1.0s 記憶體限制 256.0mb 問題描述 x 國王有乙個地宮寶庫。是 n x m 個格仔的矩陣。每個格仔放一件寶貝。每個寶貝貼著價值標籤。地宮的入口在左上角,出口在右下角。小明被帶到地宮的入口,國王要求他只能向右或向下行走。走過某個格仔時,如果那個格仔中的寶貝價值...