习题:蒜头君的城堡之旅

题目:
蒜国地域是一个 n 行 m 列的矩阵,下标均从1 开始。蒜国有个美丽的城堡,在坐标 (n,m) 上,蒜头君在坐标 (1,1) 的位置上。蒜头君打算出发去城堡游玩,游玩结束后返回到起点。在出发去城堡的路上,蒜头君只会选择往下或者往右走,而在返回的路上,蒜头君只会选择往上或者往左走,每次只能走一格。已知每个格子上都有一定数量的蒜味可乐,每个格子至多经过一次。
现在蒜头君请你来帮他计算一下,如何计划来回行程,可以收集到最多的蒜味可乐。

输入格式:
第一行输入两个整数 n,m(1≤n,m≤50),表示蒜国是一个 n 行 m 列的矩阵。
接下来输入 n 行,每行输入 m 个整数,代表一个 n×m的矩阵,每个整数代表对应位置上的蒜味可乐数量,每行的每两个整数之间用一个空格隔开。其中蒜头君的位置和城堡的位置上没有蒜味可乐,用 0 表示,其余位置上的整数范围在 [1,100] 内。

输出格式:
输出一行,输出一个整数,表示蒜头君在来回路上能收集到的蒜味可乐的最大值。

import java.util.Scanner;
/*
 样例输入
3 3
0 2 9
4 8 6
2 7 0
样例输出
36
*/
class Main {
	 public static void main(String[] args) {
		 Scanner sc = new Scanner(System.in);
		 
		 int n = sc.nextInt();
		 int m = sc.nextInt();
		 int max = 0;//(1,1)到(n,m)的最大路径
		 int maxn = 0;//(n,m)返回(1,1)的最大路径
		  
		 int [][] f = new int [n+1][m+1];//地图
		 int [][] dp = new int [n+1][m+1];//到每点的最大路径
		
		 for(int i=1;i<=n;i++) {
			 for(int j=1;j<=m;j++) {
				 int d = sc.nextInt();
				 f[i][j] = d;
			 }
		 }
		
		/*找(n,m)点*/
		 for(int i=1;i<=n;i++) {
			 for(int j=1;j<=m;j++) {
				 if(i==1&&j==1) {
					 continue;	 
				 }
				 if(i==1) {
					 dp[i][j] = dp[i][j-1]+f[i][j];
					 
				 }
				 if(j==1) {
					 dp[i][j] = dp[i-1][j] + f[i][j];
					
				 }
				 
				 int x =  (dp[i-1][j] > dp[i][j-1])?dp[i-1][j] : dp[i][j-1];
				dp[i][j] = x +f[i][j];	 
			 }
		 }
		 max = dp[n][m];
	
		 
		 /*清空已走过的点*/
		 int x = n,y = m;
		 while(x!=1&&y!=1) {
			 if(dp[x-1][y] > dp[x][y-1]){
				 f[x-1][y] = 0;
				 x = x-1;
			 }
			 else {
				 f[x][y-1] = 0;
				 y=y-1;
			 }

		}
		 
		 
		/*初始化dp[][]*/
		 for(int i=1;i<=n;i++) {
			 for(int j=1;j<=m;j++) {
				 dp[i][j] = 0;
			 }
		 }
		 
		 
         /*找(1,1)点*/
		 for(int i=n;i>=1;i--) {
			 for(int j=m;j>=1;j--) {
				 if(i==n&&j==m) {
					 continue;
				 }
				 else if(i==n) {
					 dp[i][j] = dp[i][j+1]+f[i][j];
				 }
				 else if(j==m) {
					 dp[i][j] = dp[i+1][j] + f[i][j];
				 }
				 else {
				    int c =  (dp[i+1][j] > dp[i][j+1])?dp[i+1][j] : dp[i][j+1];
				    dp[i][j] = c +f[i][j];	 
				 }
			 } 
		 }
		 maxn = max + dp[1][1];
		 
		 System.out.println(maxn);
	
	
		}
	 
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值