PTA 寻宝路线 (40 point(s))

寻宝路线 (40 point(s))

在一个m行n列方格矩阵中,每一个方格内摆放着价值不等的宝贝(价值可正可负),让小明感到好奇的是,从左上角到达右下角的所有可能路线中,能捡到宝贝的价值总和最大是多少?而且这种达到最大值的路线 又有多少条?【注意:只能从一个格子向下或向右走到相邻格子,并且走到的格子宝贝一定会被捡起。】

输入格式:

第一行为整数m,n(均不大于100),
下一行开始会有一个m行n列的整数方阵,
对应方格矩阵中的宝贝价值(这些值的绝对值都不超过500)。

输出格式:

单独一行输出2个整数,
分别为能捡到宝贝价值总和的最大值和达到最大值的路线数量,
2个整数间隔一个空格。

输入样例:

在这里给出一组输入。例如:

4  5
2  -1  6  -2  9
-3  2  5  -5  1
5   8  3  -2  4
5   2  8  -4  7

输出样例:
对应的输出为:

26 3

java dfs

import java.io.*;
import java.util.*;

public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(new BufferedInputStream(System.in));
		m = in.nextInt();
		n = in.nextInt();
		int[][] a = new int[m][n];
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < n; j++) {
				a[i][j] = in.nextInt();
			}
		}
		in.close();
		dfs(a, 0, 0, 0);
		Integer max = Collections.max(map.keySet());
		System.out.println(max + " " + map.get(max));

	}

	static int m = 0, n = 0;

	static HashMap<Integer, Integer> map = new HashMap<>();

	private static void dfs(int[][] a, int i, int j, int q) {
		if (i == a.length - 1 && j == a[0].length - 1) {
			q += a[m - 1][n - 1];
			map.put(q, map.getOrDefault(q, 0) + 1);
			q -= a[m - 1][n - 1];
			return;
		}
		if (i == m - 1) {
			dfs(a, i, j + 1, q + a[i][j]);
		} else if (j == n - 1) {
			dfs(a, i + 1, j, q + a[i][j]);
		} else {
			dfs(a, i + 1, j, q + a[i][j]);
			dfs(a, i, j + 1, q + a[i][j]);
		}
	}

}

动态规划

import java.io.*;
import java.util.*;

// import algorithms.Util;

public class Main {

	static int[][] dp;
	static int[][] a;
	static int[][] dir = { { 0, -1 }, { -1, 0 } };
	static int ans = 0;
	static int m, n;

	static void dfs(int sum, int row, int col) {
		if (sum == a[1][1]) {
			ans++;
			return;
		} else {
			for (int k = 0; k < 2; ++k) {
				int rr = row + dir[k][0];
				int cc = col + dir[k][1];
				if (rr < 1 || cc < 1 || rr > m || cc > n)
					continue;
				if (sum - a[row][col] == dp[rr][cc]) {
					dfs(sum - a[row][col], rr, cc);
				}
			}
		}
	}

	public static void main(String[] args) {
		Scanner in = new Scanner(new BufferedInputStream(System.in));
		m = in.nextInt();
		n = in.nextInt();
		dp = new int[m + 1][n + 1];
		a = new int[m + 1][n + 1];
		// a
		for (int i = 1; i <= m; ++i) {
			for (int j = 1; j <= n; ++j)
				a[i][j] = in.nextInt();
		}
		// dp
		for (int i = 1; i <= m; ++i) {
			for (int j = 1; j <= n; ++j) {
				// 因为有正负
				if (j == 1)
					dp[i][j] = dp[i - 1][j] + a[i][j];
				else if (i == 1)
					dp[i][j] = dp[i][j - 1] + a[i][j];
				else
					dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]) + a[i][j];
			}
		}
		// Util.print(dp);
		System.out.print(dp[m][n] + " ");

		dfs(dp[m][n], m, n);

		System.out.println(ans);
	}

}

很遗憾 因为
Author
高见元
Organization
湖北经济学院
Code Size Limit
16 KB
Time Limit
1000 ms
Memory Limit
1 MB
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SVIP_Quanw

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值