P1123 取数游戏

 

说明/提示

对于第1组数据,取数方式如下:

[67] 75 63 10

29 29 [92] 14

[21] 68 71 56

8 67 [91] 25

====>>洛谷

————————————————————分隔线————————————————————————————————————

对于这种题目,如果要求不高的话,要求最大值,一般都可以用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]]--; } } } }
原文地址:https://www.cnblogs.com/WakingShaw/p/12945394.html