当前位置: 首页 > news >正文

数据结构与算法--蛇行矩阵问题

题目描述

给定一个矩阵matrix,值有正、负、0

蛇可以空降到最左列的任何一个位置,初始增长值是0
蛇每一步可以选择右上、右、右下三个方向的任何一个前进
沿途的数字累加起来,作为增长值;但是蛇一旦增长值为负数,就会死去
蛇有一种能力,可以使用一次:把某个格子里的数变成相反数
蛇可以走到任何格子的时候停止
返回蛇能获得的最大增长值


import java.util.Arrays;public class Code04_SnakeGame {public static int maxValue(int[][] matrix){if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {return 0;}int ans = 0;for (int i = 0; i < matrix.length; i++) {for (int j = 0; j < matrix[0].length; j++) {Info res = f(matrix,i,j);ans = Math.max(ans, Math.max(res.no,res.yes));}}return ans;}public static class Info{int no;int yes;public Info(int no, int yes){this.no = no;this.yes = yes;}}public static Info f(int[][] matrix, int i, int j){if(j == 0){int no = Math.max(-1, matrix[i][0]);int yes = Math.max(-1, -matrix[i][0]);return new Info(no,yes);}//Info ans = new Info();int preNo = -1;int preYes = -1;Info preInfo = f(matrix,i,j-1);preNo = Math.max(-1, preInfo.no);preYes = Math.max(-1, preInfo.yes);if(i > 0){preInfo = f(matrix,i-1,j-1);preNo = Math.max(-1,Math.max(preNo, preInfo.no));preYes = Math.max(-1,Math.max(preYes, preInfo.yes));}if(i < matrix.length-1){preInfo = f(matrix,i+1,j-1);preNo = Math.max(-1,Math.max(preNo, preInfo.no));preYes = Math.max(-1,Math.max(preYes, preInfo.yes));}int no = preNo == -1 ? -1 : Math.max(-1, preNo + matrix[i][j]);int p1 = preYes == -1 ? -1 : Math.max(-1, preYes + matrix[i][j]);int p2 = preNo == -1 ? -1 : Math.max(-1, preNo - matrix[i][j]);int yes = Math.max(-1, Math.max(p1,p2));return new Info(no,yes);}// 从假想的最优左侧到达(i,j)的旅程中// 0) 在没有使用过能力的情况下,返回路径最大和,没有可能到达的话,返回负// 1) 在使用过能力的情况下,返回路径最大和,没有可能到达的话,返回负public static int[] process(int[][] m, int i, int j) {if (j == 0) { // (i,j)就是最左侧的位置return new int[] { m[i][j], -m[i][j] };}int[] preAns = process(m, i, j - 1);// 所有的路中,完全不使用能力的情况下,能够到达的最好长度是多大int preUnuse = preAns[0];// 所有的路中,使用过一次能力的情况下,能够到达的最好长度是多大int preUse = preAns[1];if (i - 1 >= 0) {preAns = process(m, i - 1, j - 1);preUnuse = Math.max(preUnuse, preAns[0]);preUse = Math.max(preUse, preAns[1]);}if (i + 1 < m.length) {preAns = process(m, i + 1, j - 1);preUnuse = Math.max(preUnuse, preAns[0]);preUse = Math.max(preUse, preAns[1]);}// preUnuse 之前旅程,没用过能力// preUse 之前旅程,已经使用过能力了int no = -1; // 之前没使用过能力,当前位置也不使用能力,的最优解int yes = -1; // 不管是之前使用能力,还是当前使用了能力,请保证能力只使用一次,最优解if (preUnuse >= 0) {no = m[i][j] + preUnuse;yes = -m[i][j] + preUnuse;}if (preUse >= 0) {yes = Math.max(yes, m[i][j] + preUse);}return new int[] { no, yes };}public static int walk2(int[][] matrix) {if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {return 0;}int max = Integer.MIN_VALUE;int[][][] dp = new int[matrix.length][matrix[0].length][2];for (int i = 0; i < dp.length; i++) {dp[i][0][0] = matrix[i][0];dp[i][0][1] = -matrix[i][0];max = Math.max(max, Math.max(dp[i][0][0], dp[i][0][1]));}for (int j = 1; j < matrix[0].length; j++) {for (int i = 0; i < matrix.length; i++) {int preUnuse = dp[i][j - 1][0];int preUse = dp[i][j - 1][1];if (i - 1 >= 0) {preUnuse = Math.max(preUnuse, dp[i - 1][j - 1][0]);preUse = Math.max(preUse, dp[i - 1][j - 1][1]);}if (i + 1 < matrix.length) {preUnuse = Math.max(preUnuse, dp[i + 1][j - 1][0]);preUse = Math.max(preUse, dp[i + 1][j - 1][1]);}dp[i][j][0] = -1;dp[i][j][1] = -1;if (preUnuse >= 0) {dp[i][j][0] = matrix[i][j] + preUnuse;dp[i][j][1] = -matrix[i][j] + preUnuse;}if (preUse >= 0) {dp[i][j][1] = Math.max(dp[i][j][1], matrix[i][j] + preUse);}max = Math.max(max, Math.max(dp[i][j][0], dp[i][j][1]));}}return max;}public static int[][] generateRandomArray(int row, int col, int value) {int[][] arr = new int[row][col];for (int i = 0; i < arr.length; i++) {for (int j = 0; j < arr[0].length; j++) {arr[i][j] = (int) (Math.random() * value) * (Math.random() > 0.5 ? -1 : 1);}}return arr;}public static void main(String[] args) {int N = 7;int M = 7;int V = 10;int times = 1000000;for (int i = 0; i < times; i++) {int r = (int) (Math.random() * (N + 1));int c = (int) (Math.random() * (M + 1));int[][] matrix = generateRandomArray(r, c, V);int ans1 = maxValue(matrix);int ans2 = walk2(matrix);if (ans1 != ans2) {for (int j = 0; j < matrix.length; j++) {System.out.println(Arrays.toString(matrix[j]));}System.out.println("Oops   ans1: " + ans1 + "   ans2:" + ans2);break;}}System.out.println("finish");}
}
http://www.dtcms.com/a/263968.html

相关文章:

  • WPF学习笔记(17)样式Style
  • 【机器学习2】正则化regularizaiton(降低模型过拟合)
  • Http、Ftp、Dns和Dhcp服务器搭建
  • Go 服务如何“主动”通知用户?SSE广播与断线重连实战
  • 从docker-compose快速入门Docker
  • VCenter SSL过期,登录提示HTTP 500错误解决办法
  • Linux驱动学习day13(同步与互斥)
  • 记录一次生产环境ActiveMQ无法启动的问题
  • 变幻莫测:CoreData 中 Transformable 类型面面俱到(八)
  • Raspberry Pi 4边缘智能PLC:OpenPLC赋能物联网
  • 25-7-1 论文学习(1)- Fractal Generative Models 何恺明大佬的论文
  • 半导体和PN结
  • 遥感影像岩性分类:基于CNN与CNN-EL集成学习的深度学习方法
  • 胖喵安初 (azi) Android 应用初始化库 (类似 Termux)
  • Adobe AI高效设计技巧与创新思维指南
  • day41简单CNN
  • 注意力得分矩阵求解例子
  • 网站崩溃的幕后黑手:GPTBot爬虫的流量冲击
  • 第七讲~~测试工具(禅道项目管理系统)
  • 【记录】Word|Word创建自动编号的多级列表标题样式
  • poi java 删除word的空白页
  • 【docker】docker save和docker load
  • 通达信【极弱强势指标与股道波段交易系统】幅图
  • Gin 中间件详解与实践
  • 发布/订阅模式:解耦系统的强大设计模式
  • Python Flask 容器化应用链路可观测
  • 基于SSM万华城市货运服务系统的设计与实现
  • 开源模型与商用模型协同开发机制设计
  • Vue基础(19)_Vue内置指令
  • Qt_Creator入门基础知识