现在有一个8*8的棋盘,上面放着64个价值不等的礼物,每个小的棋盘上面放置一个礼物(礼物的价值大于0小于1000),一个人的初始位置在棋盘的左上角,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,结束位置在棋盘的右下角,请设计一个算法使其能够获得最大价值的礼物。
输入包含多个测试用例,每个测试用例共有8行8列,第i行的第j列的数字代表了该处棋盘上的礼物的价值,每两个数之间用空格隔开。
对于每组测试用例,请输出你能够获得最大价值的礼物。
2 8 15 1 10 5 19 19 3 5 6 6 2 8 2 12 16 3 8 17 12 5 3 14 13 3 2 17 19 16 8 7 12 19 10 13 8 20 16 15 4 12 3 14 14 5 2 12 14 9 8 5 3 18 18 20 4 2 10 19 17 16 11 3
194
关键还是需要看出这个可以通过动态规划解决,找到递归公式 就基本搞定了~
package Array; import java.util.Scanner; /** * @Title: Bigest.java * @Package Array * @Description: TODO * @author nutc * @date 2013-8-18 下午7:30:45 * @version V1.0 */ public class Bigest { public static void main(String args[]) { int L=8; int[][] array = new int[L][L]; // int limit; Scanner sc = new Scanner(System.in); while (sc.hasNext()) { // limit = sc.nextInt(); for (int i = 0; i < L; i++) { for (int j = 0; j < L; j++) { array[i][j] = sc.nextInt(); } } System.out.println(find(array)); // int result = findlimit(array, L-1, L-1, limit, limit); // if (result <0) //TODO // System.out.println("-1"); // else // System.out.println(result); } } // public static int findlimit(int[][] a, int i, int j, int limit, int sum) { //// System.out.println(i+" "+j+" "+sum); // if (sum < 0 || i < 0 || j < 0) // return Integer.MIN_VALUE; // // if (i == 0 && j == 0) { // if (sum >= a[i][j]) // return a[i][j]; // else // return Integer.MIN_VALUE; // } // // int sum1 = Integer.MIN_VALUE, sum2 = sum1; // sum1 = findlimit(a, i - 1, j, limit, sum - a[i][j]); // sum2 = findlimit(a, i, j - 1, limit, sum - a[i][j]); // int now = sum1 > sum2 ? sum1 : sum2; // return now + a[i][j]; // } public static int find(int[][] a) { if (a == null) return 0; int[][] sum = a; for (int i = 0; i < a.length; i++) { for (int j = 0; j < a[0].length; j++) { if (i == 0 && j == 0) continue; int val1 = -1, val2 = -1; if (i - 1 >= 0) val1 = sum[i - 1][j]; if (j - 1 >= 0) val2 = sum[i][j - 1]; sum[i][j] += val1 > val2 ? val1 : val2; } } return sum[sum.length - 1][sum.length - 1]; } }
拓展:
现在有一个8*8的棋盘,上面放着64个不同价值的礼物,每个小的棋盘上面放置一个礼物(礼物的价值大于0小于100),一个人初始位置在棋盘的左上角,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,结束位置在棋盘的右下角。从棋盘的左上角移动到右下角的时候的,每次他只能向下或向右移动一步,并拿走对应棋盘上的礼物,但是拿到的所有的礼物的价值之和不大于一个限定值limit,请设计一个算法请实现,使其能够获得不超过限制值limit的最大价值的礼物。
输入包含多个测试用例,每个测试用例共有9行,第一行是一个限制值limit<=1000,下面还有8行8列,第i行的第j列的数字代表了该处棋盘上的礼物的价值,每两个数之间用空格隔开。
对于每组测试用例,请输出你能够获得不超过限制值limit的最大价值的礼物。若没有符合条件的线路则输出-1。
90 4 2 5 1 3 8 9 7 4 5 2 3 7 1 8 6 7 2 1 8 5 9 3 6 2 8 9 5 6 3 1 7 1 2 4 5 3 7 9 6 3 5 7 8 9 6 2 4 10 8 1 4 7 5 3 9 7 4 6 2 1 3 9 8
90
写之前没有想好》。。乱七八糟的写了很久。。。所以敲代码之前把公式一定要写好:)~~~~~~~
package Array; import java.util.Scanner; /** * @Title: Bigest.java * @Package Array * @Description: TODO * @author nutc * @date 2013-8-18 下午7:30:45 * @version V1.0 */ public class Bigest { public static void main(String args[]) { int L = 8; int[][] array = new int[L][L]; int limit; Scanner sc = new Scanner(System.in); while (sc.hasNext()) { limit = sc.nextInt(); for (int i = 0; i < L; i++) { for (int j = 0; j < L; j++) { array[i][j] = sc.nextInt(); } } // System.out.println(find(array)); int result = findlimit(array, L - 1, L - 1, limit, limit); if (result == Integer.MIN_VALUE) System.out.println("-1"); else System.out.println(result); } } public static int findlimit(int[][] a, int i, int j, int limit, int sum) { // 先把递归公式先写出来.....比神马都重要!!!!!! // System.out.println(i+" "+j+" "+sum); if (sum < 0 || i < 0 || j < 0) return Integer.MIN_VALUE; if (i == 0 && j == 0) { if (sum >= a[i][j]) return a[i][j]; else return Integer.MIN_VALUE; } int sum1 = Integer.MIN_VALUE, sum2 = sum1; sum1 = findlimit(a, i - 1, j, limit, sum - a[i][j]); sum2 = findlimit(a, i, j - 1, limit, sum - a[i][j]); int now = sum1 > sum2 ? sum1 : sum2; if (now != Integer.MIN_VALUE) now += a[i][j]; return now; } // public static int find(int[][] a) { // if (a == null) // return 0; // // int[][] sum = a; // // for (int i = 0; i < a.length; i++) { // for (int j = 0; j < a[0].length; j++) { // if (i == 0 && j == 0) // continue; // int val1 = -1, val2 = -1; // if (i - 1 >= 0) // val1 = sum[i - 1][j]; // if (j - 1 >= 0) // val2 = sum[i][j - 1]; // sum[i][j] += val1 > val2 ? val1 : val2; // } // } // return sum[sum.length - 1][sum.length - 1]; // } }//
A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).
The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).
How many possible unique paths are there?
Above is a 3 x 7 grid. How many possible unique paths are there?
Note: m and n will be at most 100.
public class Solution { public int uniquePaths(int m, int n) { if(m<=0||n<=0) return 0; int[][] path =new int [m][n]; for(int i=0;i<n;i++) path[0][i]=1; for(int i=0;i<m;i++) path[i][0]=1; for(int i=1;i<m;i++){ for(int j=1;j<n;j++){ path[i][j]+=path[i-1][j]; path[i][j]+=path[i][j-1]; } } return path[m-1][n-1]; } }
Unique Paths II
Mar 29 '12
4573 / 11497
Follow up for "Unique Paths":
Now consider if some obstacles are added to the grids. How many unique paths would there be?
An obstacle and empty space is marked as 1 and 0 respectively in the grid.
For example,
There is one obstacle in the middle of a 3x3 grid as illustrated below.
[
[0,0,0],
[0,1,0],
[0,0,0]
]
The total number of unique paths is 2.
Note: m and n will be at most 100.
public class Solution { public int uniquePathsWithObstacles(int[][] obstacleGrid) { if(obstacleGrid==null) return 0; int m = obstacleGrid.length; int n = obstacleGrid[0].length; //注意这里起点和终点有可能是1,当然询问下面试官是最好的 if(obstacleGrid[0][0]==1||obstacleGrid[m-1][n-1]==1) return 0; int[][] path =new int [m][n]; path[0][0]=1; for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ if(i-1>=0 && obstacleGrid[i-1][j]!=1) path[i][j]+=path[i-1][j]; if(j-1>=0 && obstacleGrid[i][j-1]!=1) //这里j-1>0的等号忘记了.... path[i][j]+=path[i][j-1]; } } return path[m-1][n-1]; } }