二维数组--从左上角到右下角的最大值 九度

题目描述:

现在有一个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];  
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值