Acwing 1027 方格取數(四維dp)

2021-09-27 13:30:39 字數 1841 閱讀 7617

傳送門

設有 n×n 的方格圖,我們在其中的某些方格中填入正整數,而其它的方格中則放入數字0。如下圖所示:

某人從圖中的左上角 a 出發,可以向下行走,也可以向右行走,直到到達右下角的 b 點。

在走過的路上,他可以取走方格中的數(取走後的方格中將變為數字0)。

此人從 a 點到 b 點共走了兩次,試找出兩條這樣的路徑,使得取得的數字和為最大。

輸入格式

第一行為乙個整數n,表示 n×n 的方格圖。

接下來的每行有三個整數,第乙個為行號數,第二個為列號數,第三個為在該行、該列上所放的數。

一行「0 0 0」表示結束。

輸出格式

輸出乙個整數,表示兩條路徑上取得的最大的和。

資料範圍

n≤10

輸入樣例:

82 3 13

2 6 6

3 5 7

4 4 14

5 2 21

5 6 4

6 3 15

7 2 14

0 0 0

輸出樣例:

67做法1:dfs第一次走的所有路徑,將走過的點標記一下,終點進行正常二維dp。

做法2:四維dp,dp[i][j][k][r] 表示有兩個人同時走,第乙個人走到(i, j) 第二個人走到(k, r)的時候能獲得的最大價值。

兩個人都要從上邊或者左邊的格仔轉移過來,那麼有四種不同的轉移方式,轉移方程是:dp[i][j][k][r] = max(dp[i-1][j][k][r], dp[i-1][j][k][r-1], dp[i][j-1][k-1][r], dp[i][j-1][k][r-1])+a[i][j]+a[k][r]

如果兩個人走到同乙個點,a[i][j] 和 a[k][r]只能加一次,那麼減掉乙個就好。

做法1 : dfs+dp 做法 :

#include

#include

#include

using namespace std;

const int n=15

;int a[n]

[n],vis[n]

[n],dp[n]

[n],ans,n;

void dfs

(int x,int y,int sum)

ans=

max(ans,sum+dp[n]

[n]);}

dfs(x+

1,y,sum+a[x+1]

[y])

; vis[x+1]

[y]=0;

dfs(x,y+

1,sum+a[x]

[y+1])

; vis[x]

[y+1]=

0;}int main()

做法2: 四維dp做法

#include

#include

#include

using namespace std;

const

int n =15;

int a[n]

[n],dp[n]

[n][n]

[n];

intmain()

cout<

[n][n]

[n]<

return0;

}

1277 方格取數

設有n n的方格圖,我們在其中的某些方格中填入正整數,而其它的方格中則放入數字0。如下圖所示 某人從圖中的左上角a出發,可以向下行走,也可以向右行走,直到到達右下角的b點。在走過的路上,他可以取走方格中的數 取走後的方格中將變為數字0 此人從a點到b點共走了兩次,試找出兩條這樣的路徑,使得取得的數字...

1907 方格取數 3

時間限制 2 s 空間限制 256000 kb 題目等級 大師 master 題解檢視執行結果 問題描述 在乙個有m n 個方格的棋盤中,每個方格中有乙個正整數。現要從方格中取數,使任 意2 個數所在方格沒有公共邊,且取出的數的總和最大。試設計乙個滿足要求的取數演算法。程式設計任務 對於給定的方格棋...

1227 方格取數 2

給出乙個n n的矩陣,每一格有乙個非負整數aij,aij 1000 現在從 1,1 出發,可以往右或者往下走,最後到達 n,n 每達到一格,把該格仔的數取出來,該格仔的數就變成0,這樣一共走k次,現在要求k次所達到的方格的數的和最大 輸入格式 第一行兩個數n,k 1 n 50,0 k 10 接下來n...