藍橋杯 地宮取寶(動態規劃)

2022-06-23 21:45:09 字數 2295 閱讀 8932

題面如下:

x 國王有一個地宮寶庫,是 n×m

'>n×m

個格子的矩陣,每個格子放一件寶貝,每個寶貝貼著價值標籤。

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

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

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

當小明走到出口時,如果他手中的寶貝恰好是 k

'>k

k 件,則這些寶貝就可以送給小明。

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

'>k

k 件寶貝。

輸入格式

第一行 3

'>3

個整數,n,m

,k'>n,m,k

,含義見題目描述。

接下來 n

'>n

行,每行有 m

'>m

個整數 c

i'>ci

用來描述寶庫矩陣每個格子的寶貝價值。

輸出格式

輸出一個整數,表示正好取 k

'>k

個寶貝的行動方案數。

該數字可能很大,輸出它對 1000000007

'>1000000007

取模的結果。

資料範圍1≤

n,m≤

50'>1≤n,m≤501≤

k≤12'>1≤k≤120≤

ci≤12

'>0≤ci≤12

輸入樣例1:

2 2 2

1 22 1

輸出樣例1:
2
輸入樣例2:
2 3 2

1 2 3

2 1 5

輸出樣例2:

這個題的題目資料範圍很小,可以預估是一個維數較多的dp,我最開始的思路如下(雖然這個思路不對,但是ac思路是在這個基礎上做了一點很小的調整):

每個點都只能往下或者往右移動,可以選擇拿走下面/右面的寶物,也可以不拿,如果拿了,k維度上升一層,否則仍然在這一層,同時維護當前手中最大的物品重量就可以了

列舉順序和lintcode114 unique paths等走迷宮類似的題目的列舉順序一樣,一行行計算即可,只不過多加了一重k的限制

起始點寶物的拾取不能按照上述規則處理,所以在最開始單獨給dp[0][0][1]特殊賦值一下

然後開開心心地吃了兩發wa,感覺事情不對勁,突然意識到這個手中最大寶物重量不能直接存個最大的,舉個例子:3,3,3處有5種走法,最大重量是7;2,3,4處有6種走法,最大重量是9,這兩個位置都能來到3,3,4這個位置,雖然方案數看著可以合併,但是他們最大重量是不同的,所以實際上不能直接合並(3,3,4這個點需要記錄著有5種走法的最大重量是7;有6種走法的最大重量是9,不然面臨一個重量為8的寶物,你是沒辦法處理的),所以。。我們還要再加一層陣列,把它變成四維陣列,其中第四維表示最大重量,這樣我們的dp陣列表示的含義就變成了下面這樣:

dp[i][j][t][p]表示位置在i,j處,當前已經拿了t個物品,這些物品中的最大重量是p的方案個數有多少種,轉移方程沒太大變化,就是加了一個第四維的迴圈

ac**如下:

#include #include 

#include

#include

using

namespace

std;

#define modulus 1000000007

long

long arr[55][55][13][14

];int weight[55][55

];int

main()

}arr[

0][0][0][0] = 1

; arr[

0][0][1][weight[0][0]] = 1

;

for(int i = 0; i < n; i++)

if(weight[i][j+1] >p)

}//cout << "i=" << i <

//cout << arr[i][j][t] << endl;

} }

}int sum = 0

;

for(int i = 0; i < 14; i++)

cout

<< sum <

return0;

}