1. 程式人生 > >D 探 尋 寶 藏(雙執行緒DP)

D 探 尋 寶 藏(雙執行緒DP)

題目連結:D 探 尋 寶 藏

D 探 尋 寶 藏

記憶體限制:64MB 時間限制:1s Special Judge: No

題目描述:
傳說HMH大沙漠中有一個M*N迷宮,裡面藏有許多寶物。某天,Dr.Kong找到了迷宮的地圖,他發現迷宮內處處有寶物,最珍貴的寶物就藏在右下角,迷宮的進出口在左上角。當然,迷宮中的通路不是平坦的,到處都是陷阱。Dr.Kong決定讓他的機器人卡多去探險。

但機器人卡多從左上角走到右下角時,只會向下走或者向右走。從右下角往回走到左上角時,只會向上走或者向左走,而且卡多不走回頭路。(即:一個點最多經過一次)。當然卡多順手也拿走沿路的每個寶物。

Dr.Kong希望他的機器人卡多儘量多地帶出寶物。請你編寫程式,幫助Dr.Kong計算一下,卡多最多能帶出多少寶物。
輸入描述:
第一行: K 表示有多少組測試資料。
接下來對每組測試資料:
第1行: M N
第2~M+1行: Ai1 Ai2 ……AiN (i=1,…..,m)

【約束條件】
2≤k≤5 1≤M, N≤50 0≤Aij≤100 (i=1,….,M; j=1,…,N)
所有資料都是整數。 資料之間有一個空格。
輸出描述:
對於每組測試資料,輸出一行:機器人卡多攜帶出最多價值的寶物數
樣例輸入:
複製
2
2 3
0 10 10
10 10 80
3 3
0 3 9
2 8 5
5 7 100
樣例輸出:
120
134

這道題與:傳紙條(一)一個型別。

思路:雙執行緒DP,從左上角到右下角,再從右下角到左上角,不能走走過的位置,就是一步走兩個位置,用四維陣列記錄,。

程式碼:

#include<stdio.h>
#include<string.h> #include<algorithm> using namespace std; #define mem(a,b) memset(a,b,sizeof(a)) const int maxn=55; int dp[maxn][maxn][maxn][maxn]; int ma[maxn][maxn]; int Max(int a,int b,int c,int d) { int f[5]; f[0]=a; f[1]=b; f[2]=c; f[3]=d; sort(f,f+4); return
f[3]; } int main() { int t,n,m; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); mem(dp,0); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&ma[i][j]); for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { for(int x=i+1;x<=n;x++)//【x,y】的x一定是從i+1開始的 { int y=i+j-x;//【i,j】和【x,y】的步數是一樣的 if(y<=0) continue; //有四種走法,到達[i][j],[x][y]這倆點 dp[i][j][x][y]=Max(dp[i][j-1][x][y-1],dp[i][j-1][x-1][y],dp[i-1][j][x][y-1],dp[i-1][j][x-1][y])+ma[i][j]+ma[x][y]; } } } dp[n][m][n][m]=max(dp[n][m-1][n-1][m],dp[n-1][m][n][m-1])+ma[n][m];//因為【i,j】和【x,y】相同的點是遍歷不到的,所以要計算一下。 printf("%d\n",dp[n][m][n][m]); } return 0; }