一個N×M的由非負整數構成的數字矩陣,你須要在其中取出若干個數字,使得取出的任意兩個數字不相鄰(若一個數字在另一個數字相鄰88個格子中的一個即認爲這兩個數字相鄰),求取出數字和最大是多少。html
第1行有一個正整數T,表示了有T組數據。java
對於每一組數據,第一行有兩個正整數N和M,表示了數字矩陣爲N行M列。c++
接下來N行,每行M個非負整數,描述了這個數字矩陣。算法
T行,每行一個非負整數,輸出所求得的答案。spa
對於第1組數據,取數方式以下:code
[67] 75 63 10htm
29 29 [92] 14blog
[21] 68 71 56it
8 67 [91] 25class
====>>洛谷
————————————————————分隔線————————————————————————————————————
對於這種題目,若是要求不高的話,要求最大值,通常均可以用DFS算法,枚舉各類可能的值,而後比較便可得出結果。這道題有點棘手的地方在於,一個數,要標記其是否已被訪問,由於是八方向,狀況彷佛有多種,用Boolean來記錄的話, 貌似不太可行。咱們能夠用一個int類型的變量來記錄,當這個數被訪問時,該變量自增,當回溯時,該變量自減==>因此當該變量爲零時,該數未被訪問。當遇到一個數時,有取與不取兩種選擇,這兩種選擇咱們都應該嘗試一遍。
源代碼:
import java.util.Scanner; public class Main { static int T, N, M, Max; static int[][] nums = new int[10][10]; static int[][] visited = new int[10][10];
//左上,上, 右上,左,右,左下,下,右下 static int[] dx = {-1, -1, -1, 0, 0, 1, 1, 1}; static int[] dy = {-1, 0, 1, -1, 1, -1, 0, 1}; public static void main(String[] args) { Scanner sc = new Scanner(System.in); T = sc.nextInt(); for(int i = 0; i < T; i++) { N = sc.nextInt(); M = sc.nextInt(); for(int r = 0; r < N; r++) { for(int c = 0; c < M; c++) { nums[r][c] = sc.nextInt(); visited[r][c] = 0; } } Max = 0; DFS(0, 0, 0); System.out.println(Max); } } public static void DFS(int x, int y, int sum) { if(y >= M) { y = 0; x = x + 1; if(x >= N) { Max = Max > sum ? Max : sum; return; } } DFS(x, y+1, sum); //不取該數
//取該數 if(visited[x][y] == 0) { for(int i = 0; i < 8; i++) { if(x+dx[i] >= 0 && y+dy[i] >= 0) visited[x+dx[i]][y+dy[i]]++; } DFS(x, y+1, sum+nums[x][y]); for(int i = 0; i < 8; i++) { if(x+dx[i] >= 0 && y+dy[i] >= 0) visited[x+dx[i]][y+dy[i]]--; } } } }