小东所在公司要发年终奖,而小东恰好获得了最高福利,他要在公司年会上参与一个抽奖游戏,游戏在一个6*6的棋盘上进行,上面放着36个价值不等的礼物,每个小的棋盘上面放置着一个礼物,他需要从左上角开始游戏,每次只能向下或者向右移动一步,到达右下角停止,一路上的格子里的礼物小东都能拿到,请设计一个算法使小东拿到价值最高的礼物。
给定一个6*6的矩阵board,其中每个元素为对应格子的礼物价值,左上角为[0,0],请返回能获得的最大价值,保证每个礼物价值大于100小于1000。
小东所在公司要发年终奖,而小东恰好获得了最高福利,他要在公司年会上参与一个抽奖游戏,游戏在一个6*6的棋盘上进行,上面放着36个价值不等的礼物,每个小的棋盘上面放置着一个礼物,他需要从左上角开始游戏,每次只能向下或者向右移动一步,到达右下角停止,一路上的格子里的礼物小东都能拿到,请设计一个算法使小东拿到价值最高的礼物。
给定一个6*6的矩阵board,其中每个元素为对应格子的礼物价值,左上角为[0,0],请返回能获得的最大价值,保证每个礼物价值大于100小于1000。
import java.util.*; public class Bonus { public int getMost(int[][] board) { int m=board.length,n=board[0].length; for(int i=1;i<m;i++){ board[i][0]+=board[i-1][0]; } for(int j=1;j<n;j++){ board[0][j]+=board[0][j-1]; } for(int i=1;i<m;i++){ for(int j=1;j<n;j++){ board[i][j]+=Math.max(board[i-1][j],board[i][j-1]); } } return board[m-1][n-1]; } }
//动态规划,不使用额外二维数组
import java.util.*; public class Bonus { public int getMost(int[][] board) { //初始化 int rowPre = 0; int colPre = 0; for (int i = 1; i<6; i++) { board[0][i] += rowPre; board[i][0] += colPre; rowPre = board[0][i]; colPre = board[i][0]; } // write code here for (int i=1; i<6; i++) { for (int j=1; j<6; j++) { board[i][j] += Math.max(board[i-1][j],board[i][j-1]); } } return board[5][5] + board[0][0]; } }
import java.util.*; public class Bonus { public int getMost(int[][] board) { int row = board.length; int col = board[0].length; for(int i = 1;i < row;i++){ board[i][0] = board[i - 1][0] + board[i][0]; } for(int j = 1;j < col;j++){ board[0][j] = board[0][j - 1] + board[0][j]; } for(int i = 1;i < row;i++){ for(int j = 1;j < col;j++){ board[i][j] = Math.max(board[i - 1][j],board[i][j - 1])+board[i][j]; } } return board[row - 1][col - 1]; } }
import java.util.*; public class Bonus { public int getMost(int[][] board) { // write code here if(board==null) return 0; int[][] dp=new int[7][7]; //dp[1][1]=board[0][0]; for(int i=1;i<7;i++){ for(int j=1;j<7;j++){ dp[i][j]=Math.max(dp[i][j-1],dp[i-1][j]) +board[i-1][j-1]; } } return dp[6][6]; } }dp问题,我的做法就是把dp数组左边界和上边界分别扩充一行和一列,因为我们要考虑i-1和j-1,这样处理就可以使得我们对6*6棋盘上任意格子处的状态都可以使用状态转移方程了,最后返回的就是dp数组最右下角的格子里的值就可以了.
import java.util.*; public class Bonus { public int getMost(int[][] board) { // write code here int[][] dp =new int[board.length][board[0].length]; for(int i=0;i<dp.length;i++){ for(int j=0;j<dp[0].length;j++){ if(i==0&&j==0){dp[0][0]=board[0][0];continue;} if(i==0 && dp[i][j-1]!=0 && board[i][j]>100 && board[i][j]<1000){ dp[0][j]=dp[0][j-1]+board[0][j];continue; } if(j==0 && dp[i-1][j] !=0 && board[i][j]>100 && board[i][j]<1000){ dp[i][j]=dp[i-1][j]+board[i][j];continue; } if((dp[i-1][j]!=0 || dp[i][j-1]!=0) && board[i][j]>100 && board[i][j]<1000){ dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1])+board[i][j];continue; } } } return dp[dp.length-1][dp[0].length-1]; } }
//dfs import java.util.*; public class Bonus { int value=0; public int getMost(int[][] board) { // write code here dfs(board,0,0,0); return value; } private void dfs(int[][] board, int sum, int i, int j){ if(i==5 && j==5){ value=Math.max(value,sum+board[i][j]); return; } if(i>=6 || j>=6) return; dfs(board,sum+board[i][j],i+1,j); dfs(board,sum+board[i][j],i,j+1); } }
import java.util.*; public class Bonus { public int getMost(int[][] board) { int n=board.length; // 行数 int m=board[0].length; // 列数 int[] dp=new int[m+1]; //加一列虚拟列 for (int i=0;i<n;i++){ for (int j=1;j<m+1;j++){ // 列从第二列开始 if(board[i][j-1]>100&&board[i][j-1]<1000){ dp[j]=Math.max(dp[j],dp[j-1])+board[i][j-1]; } else{ dp[j]=0; } } } return dp[m]; } }
import java.util.*; public class Bonus { public int getMost(int[][] board) { // write code here int[][] dp=new int[6][6]; //初始化数组 for(int i=0;i<6;i++){ for(int o=i;o<6;o++){ dp[i][5]+=board[o][5]; } } for(int i=0;i<6;i++){ for(int o=i;o<6;o++){ dp[5][i]+=board[5][o]; } } //递归状态方程 for(int i=4;i>=0;i--){ for(int j=4;j>=0;j--){ dp[i][j]=Math.max(dp[i+1][j]+board[i][j],dp[i][j+1]+board[i][j]); } } return dp[0][0]; } }
// 状态转移方程:dp[x][y] = max(dp[x-1][y],dp[x][y-1]) + board[x][y]; import java.util.*; public class Bonus { int[][] dp = new int[6][6]; // 存放每个位置最大价值 public int getMost(int[][] board) { return dp(board, 5, 5); } public int dp(int[][] board,int x,int y){ // 如果出界,返回0 if(x<0 || y<0)return 0; if(dp[x][y]==0){ // 如果之前未保存过当前最大位置的价值,则求之 int p1 = dp(board, x-1, y);// 从左侧过来时的最大值 int p2 = dp(board, x, y-1);// 从上册过来时的最大值 dp[x][y] = (p1>p2?p1:p2)+board[x][y];// 取上、左侧中较大的加上此位置的礼物价值即得当前位置最大礼物价值 } return dp[x][y]; // 返回当前位置礼物最大值 } }
//常规动态规划题,矩阵从左上角到右下角 import java.util.*; public class Bonus { public int getMost(int[][] board) { // write code here int[][] dp = new int[6][6]; dp[0][0] = board[0][0]; for(int i=1;i<6;i++){ dp[0][i]=dp[0][i-1]+board[0][i]; } for(int i=1;i<6;i++){ dp[i][0]=dp[i-1][0]+board[i][0]; } for(int i=1;i<6;i++){ for(int j=1;j<6;j++){ dp[i][j]=Math.max(dp[i-1][j],dp[i][j-1]) + board[i][j]; } } return dp[5][5]; } }
import java.util.*; public class Bonus { public int getMost(int[][] board) { if(board == null || board.length==0){ return 0; } for(int i=0;i<board.length;i++){ for (int j = 0; j < board[0].length; j++) { if(i==0 && j==0){ // 奖金就是第一个格子本身 }else if(i==0){ // 说明在第一行 第一行的奖金只能来自第一行左边的格子 // 奖金等于当前格子的奖金加上左边格子的奖金 board[0][j] += board[0][j-1]; }else if(j==0){ // 说明在第一列 第一列的奖金只能来自列的上面个格子 // 奖金等于当前格子的奖金加上上面格子的奖金 board[i][0] += board[i-1][0]; }else { // 来自上面或者左边的格子,选取最大奖金的。 // 最大奖金等于当前格子奖金加上左边或上面格子中奖金数大的那个 board[i][j] +=Math.max(board[i][j-1],board[i-1][j]); } } } // 增加通用型,直接用数据的长度吧 return board[board.length-1][board[0].length-1]; } }
import java.util.*; public class Bonus { public int getMost(int[][] board) { for (int i = 1; i < board.length; i ++ ) { board[i][0] += board[i - 1][0]; } for (int i = 1; i < board[0].length; i ++ ) { board[0][i] += board[0][i - 1]; } for (int i = 1; i < board.length; i ++ ) { for (int j = 1; j < board[0].length; j ++ ) { board[i][j] += Math.max(board[i - 1][j], board[i][j - 1]); } } return board[board.length - 1][board[0].length - 1]; } }
import java.util.*; public class Bonus { public int getMost(int[][] board) { // write code here int[][] dp = new int[6][6]; for (int i = 0; i < board.length; ++i) { for (int j = 0; j < board[i].length; ++j) { int tmp = board[i][j]; if (i > 0 && j > 0) { dp[i][j] = Math.max(dp[i - 1][j] + tmp, dp[i][j - 1] + tmp); } else if (i == 0 && j == 0) { dp[i][j] = tmp; } else if (i == 0) { dp[i][j] = dp[i][j - 1] + tmp; } else { dp[i][j] = dp[i - 1][j] + tmp; } } } return dp[5][5]; } }