题目描述
小M最近喜欢上了一个弹子游戏机,弹子游戏机的规则是:玩家可以在版面最上方的任意一个位置放置弹珠,弹珠经过得分点时,玩家会获得分数。玩家的目标是获得尽可能多的分数为了简化问题,这个弹子游戏机的版面只有两种组成要素:
- 第一种要素为钉子,当玩家的弹珠碰到钉子时,有可能会弹射到左下或者右下一格的位置。
- 第二种要素为得分点,当弹子经过得分点之后,可以获得得分点对应的分数。如果当前格子不为钉子(即空白或者得分点)时,弹子会往正下方落下。小M想知道,对于一个给定的版面,他最高可能获得多少分数。
输入描述:
第一行输入两个正整数n,M,代表这个版面的高为N,宽为M。
之后共行,每行包含8个整数,对于每个整数x,一1代表这个位置有一个钉子,0代表这个位置是空的,非负整数代表这个位置为得分点,经过时可以获得对应的分数。
输出措述:
输出包含一个整数,代表能获得的最高分数。
输入
3 3
-1 0 -1
100 0 0
0 50 70
输出
50
解题思路:
类似求二叉树最大权值路径问题,只不过下落有三种子路径(斜左、中、斜右),利用递归。
import java.util.Scanner;
public class test2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
int[][] nums =new int[n][m];
for(int i =0;i< n;i++){
for(int j =0;j< n;j++)
nums[i][j]=scanner.nextInt();
}
int max=0;
for(int j =0;j< n;j++){
if(getMax(n,m,0,j,nums)>max){
max=getMax(n,m,0,j,nums);
}
}
System.out.println(max);
}
public static int getMax(int n,int m,int i ,int j,int[][] nums){
if(i==n) return 0;
//最后一层
if(i==n-1) {
if(nums[i][j]==(-1)){
return 0;
}
return nums[i][j];
}
int next =0;
int nextLeaf=0;
int nextRight=0;
//垂直落体时
if(nums[i][j]!=(-1)){
next+=getMax(n,m,i+1,j,nums)+nums[i][j];
//System.out.println("line"+next);
}
//斜落
else{
//左斜落
if(j-1>=0){
nextLeaf+= Math.max(0,getMax(n,m,i+1,j-1,nums));
}
//右斜落
else{
nextRight+= Math.max(0,getMax(n,m,i+1,j+1,nums));
}
next=Math.max(nextLeaf,nextRight);
//System.out.println("bise"+next);
}
return next;
}
}