样本收集问题JAVA实现

1.题目

机器人Rob 从方形区域F 的左上角A点出发, 向下或向右行走 ,直到右下角的B 点,在走过的路上,收集方格中的样本。Rob 从A点到B 点共走2次,试找出Rob 的2条行走路径,使其取得的样本总价值最大。 
      Input:
      第1 行有1 个正整数n,表示方形区域F有n*n 个方格。接下来每行有3 个整数,前2 个表示方格位置,第3个数为该位置样本价值。最后一行是3个0。

      Output:
      将计算的最大样本总价值输出。

      Sample Input
      8
      2 3 13
      2 6 6
      3 5 7
      4 4 14
      5 2 21
      5 6 4
      6 3 15
      7 2 14
      0 0 0

     Sample Output
     67
	

2.思路

由于机器人只能向下走或向右走  ,故机器人到坐标(i,j)时所采集到的样本价值只依赖于机器人上一步的选择,即依赖于到(i-1,j)或者(i,j-1)时采集的样本总价值。 
        综上所述,此题我采用动态规划的方法解题。

1)子问题划分
设m[i,j]为机器人从坐标(1,1)出发到坐标(i,j)停下时所采集到的样本总价值

2)递推方程
        初值:m[1,i] = m[1,i]+field[1,i]   //i=1,2,...,n field是记录方形区域F中样本位置与价值的二维矩阵
             m[i,1] = m[i,1]+field[i,1]
递推式:m[i,j] = max{m[i-1,j] , m[i,j-1]} + field[i,j]

【注】此题由于要采集两次,故要调用两次动归方法,在第一次调用前还应该设计好一个二维数组记录样本采集的最大价值的路径,而在第一次调用完毕后根据记录的路径去将该路径上的样本价值标为0

3.代码

	static int n,
			   field[][];
	static String  s[][];
	
	static int collectSample(){
		int[][] m = new int[n+1][n+1];
		//初始化
		for(int i=1;i<=n;i++){
			m[1][i] += field[1][i];
			m[i][1] += field[i][1];
			s[1][i] = 1 + "," + (i-1);	
			s[i][1] = (i-1) + "," + 1;
		}
		s[1][1] = "0,0";
		for(int i=2;i<=n;i++){
			for(int j=2;j<=n;j++){
				if(m[i-1][j] > m[i][j-1]){
					m[i][j] = m[i-1][j] + field[i][j];
					s[i][j] = (i-1) + "," + j;
				}else{
					m[i][j] = m[i][j-1] + field[i][j];
					s[i][j] = i + "," + (j-1);
				}
			}
		}
		
		return m[n][n];
	}
	
	static void trace(int i,int j){
		String xy[] = s[i][j].split(",");
		int x = Integer.parseInt(xy[0]);
		int y = Integer.parseInt(xy[1]);
		field[x][y] = 0; //除去曾采集过的样本
		if(x==0 && y==0)
			return ;
		trace(x,y);
	}
	
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		n = Integer.parseInt(br.readLine());
		field = new int[n+1][n+1];
		s = new String[n+1][n+1];
		String temp;
		String sample[];
		while(!(temp=br.readLine()).equals("0")){//输入单个数0表示结束输入
			sample = temp.split(" ");
			int x = Integer.parseInt(sample[0]);
			int y = Integer.parseInt(sample[1]);
			int value = Integer.parseInt(sample[2]);
			field[x][y] = value;
		}	
		
		int first = collectSample();
		trace(n,n);//执行标记函数,除去采集过的样本
		s = new String[n+1][n+1]; //S重新初始化
		int second = first + collectSample();
		System.out.println(second);
	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值