P1123 取數遊戲(洛谷)

2022-08-17 15:36:18 字數 2051 閱讀 9777

乙個n×m的由非負整數構成的數字矩陣,你需要在其中取出若干個數字,使得取出的任意兩個數字不相鄰(若乙個數字在另外乙個數字相鄰8個格仔中的乙個即認為這兩個數字相鄰),求取出數字和最大是多少。

第1行有乙個正整數t,表示了有t組資料。

對於每一組資料,第一行有兩個正整數n和m,表示了數字矩陣為n行m列。

接下來n行,每行m個非負整數,描述了這個數字矩陣。

t行,每行乙個非負整數,輸出所求得的答案。

輸入 #1

344

6775

6310

2929

9214

2168

7156867

912523

8770

8510317

3311

11991

111

輸出 #1

271

17299

解題思路:

直接用dfs是會tle的(因為我直接用只跑通了4個測試樣例),平常dfs中我們會使用for迴圈來改變要訪問元素四個上下左右的位置,但是在此題中,dfs中套上for就會tle。因此需要有乙個更高效的移動方法:在此處,我們預設每次移動都是y+1;當時當y>m超過當前列數時,我們設定y=1(第一列)和x+1。由此看來,這個移動是固定的,而且我們可以知道下一步它的具體位置,在此方法中能確保所有位置都遍歷到。移動的終止條件是x>n超過行數時return。

我們對於每乙個位置都有取和不取值兩種情況(這樣就涵蓋了所有情況組合),從第乙個位置搜尋:取和不取先各來一次dfs。在dfs中,到達某個元素時,他有兩種狀態:能取和不能取,對於能取的:則取一次,標記為1表示取過,在dfs; 然後回溯標記0,再不取其值直接dfs,對於不能取的(表示周圍元素有被取過的): 直接dfs。

注意點:在這裡不應該找到某個位置,取其值後就立即把它周圍的元素給標記了,這樣會帶來很高的複雜度。dfs(x,y,sum)表示的是訪問到xy位置時的狀態,而且此時是否相加的情況也處理好了。因此

下面**的思路應該是訪問到某個元素後,先找到它下乙個要移動的位置,再去判斷該位置是否能取其值,若能則接下來有兩個dfs,若不能接下來有乙個dfs。

**:

1 #include2 #include3

using

namespace

std;45

intn,m;

6int a[10][10]=;

7int map[10][10]=;89

int maxx=0; //

用來存放最大值

1011

12void dfs(int x,int y,int sum)

23if(mx>n) return; //

遞迴終止條件

2425

26if(!map[mx-1][my-1]&&!map[mx][my-1]&&!map[mx+1][my-1]&&!map[mx-1][my]&&!map[mx+1][my]&&!map[mx-1][my+1]&&!map[mx][my+1]&&!map[mx+1][my+1

])31

32dfs(mx,my,sum);

3334

return;35

}36intmain()

50}

5152 memset(map,0,sizeof

(map));

53 dfs(1,1,0

);  //代表取當前第乙個數

54 memset(map,0,sizeof

(map));

55 map[1][1]=1

;56 dfs(1,1,a[1][1

]);  //代表不取當前第乙個數

57 cout5859}60

return0;

61 }

洛谷 p1123取數遊戲

定義乙個dfs函式,函式有三個變數,分別是i,j,sum。i,j分別代表訪問的這個點的座標,sum表示這條路徑上的數字的和。思路是 從 1,1 這個點進入,依次以先列數增加,然後行數增加在訪問所有的點。如下 include include include using namespace std in...

洛谷 P1123 取數遊戲

洛谷傳送門 乙個n times mn m的由非負整數構成的數字矩陣,你需要在其中取出若干個數字,使得取出的任意兩個數字不相鄰 若乙個數字在另外乙個數字相鄰88個格仔中的乙個即認為這兩個數字相鄰 求取出數字和最大是多少。第1行有乙個正整數tt,表示了有tt組資料。對於每一組資料,第一行有兩個正整數nn...

洛谷 P1123 取數遊戲

乙個n m的由非負整數構成的數字矩陣,你需要在其中取出若干個數字,使得取出的任意兩個數字不相鄰 若乙個數字在另外乙個數字相鄰8個格仔中的乙個即認為這兩個數字相鄰 求取出數字和最大是多少。輸入格式 輸入第1行有乙個正整數t,表示了有t組資料。對於每一組資料,第1行有兩個正整數n和m,表示了數字矩陣為n...