D 探 尋 寶 藏(雙執行緒DP)
阿新 • • 發佈:2019-01-02
題目連結: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;
}