1. 题目描述
小团在一个n*m的网格地图上探索。网格地图上第i行第j列的格子用坐标(ij)简记。初始时,小团的位置在地图的左上角,即坐标(1,1)。地图上的每一个格子上都有一定的金币,特别地,小团位于的初始位置(1,1)上的金币为0。小团在进行探索移动时,可以选择向右移动一格(即从(x,y)到达(x,y+1))或向下移动一格(即从(x,y)到达(x+1,y)))。地图上的每个格子都有一个颜色,红色或蓝色。
如果小团一次移动前后的两个格子颜色不同,那么他需要支付k个金币才能够完成放一次移动;如果移动前后的两个格子颜色相同,则不需要支付金币。小团可以在任意格子选择结束探索。
现在给你网格地图上每个格子的颜色与金币数量,假设小团初始时的金币数量为0,请你帮助小团计算出最优规划,使他能获得最多的金币,输出能获得的最多金币数量即可。
注意:要求保证小团任意时刻金币数量不小于零
2. 输入描述
第一行是三个用空格隔开的整数n、m和k,表示网格地图的行数为n,列数为m,在不同颜色的两个格子间移动需要支付k个金币。
接下来n行,每行是一个长度为m的字符串,字符串仅包含字符’R’或’B’。第i行字符串的第j个字符表示地图上第i行第j列的格子颜色,如果字符为’R’则表示格子颜色为红色,为’B’表示格子颜色为蓝色。
接下来是一个n行m列的非负整数矩阵,第i行第j列的数字表示地图上第i行第j列的格子上的金币数量。保证所有数据中数字大小都是介于[0,10]的整数。
1<=n,m<=200,1<=k<=5
1 7 2
BBRBRBR
0 3 2 4 1 1 1
例如:
0 B
3 B
2 R
4 B
1 R
1 B
1 R
3. 输出描述
一行一个整数,表示小团能获得的最多金币数量
output: 5
4. 样例解释
小团先从(1,1)移动到(1,2),获得3个金币;
再从(1,2)移动到(1,3),需要先支付2个金币,然后获得2个金币,此时持有3个金币;再从(1,3)移动到(1,4),需要先支付2个金币,然后获得4个金币,此时持有5个金币;然后结束探索,最终获得5个金币。
如果继续向右走,每一步都需要支付2个金币,但只获得1个金币,因此在(1,4)结束是最优的
5. Java 代码
public class Solution {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入三个字符");
String[] s = sc.nextLine().split(" ");
int n = Integer.parseInt(s[0]);
int m = Integer.parseInt(s[1]);
int k = Integer.parseInt(s[2]);
// 单个输入 --- 输入硬币数字 "" 该位置颜色 例如: 0 B
int[][] coins = new int[n][m];
char[][] colors = new char[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
String[] row = sc.nextLine().split(" ");
coins[i][j] = Integer.parseInt(row[0]);
colors[i][j] = row[1].charAt(0);
}
}
//1. 确定 dp 数组含义: dp[i][j]: 代表从 (0,0) 到 (i,j) 这个位置的最多金币数量
int[][] dp = new int[n][m];
dp[0][0] = 0; // 初始化
int ans = 0; // 记录
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
if(i>0 || j>0) dp[i][j] = -1;
else continue;
// 1. 上一步是否可以到达(如果为-1那么就是不可达)
if(i > 0 && dp[i-1][j] >= 0){
// 2.如果有颜色转换,上一步是否可以移动到此位置也就是是否大于等于K
if(colors[i-1][j] == colors[i][j]) dp[i][j] = Math.max(dp[i][j], dp[i-1][j] + coins[i][j]);
else if(dp[i-1][j] >= k) dp[i][j] = Math.max(dp[i][j], dp[i-1][j] + coins[i][j] - k);
}
// dp[i][j] = -1;
if(j > 0 && dp[i][j-1] >= 0){
if(colors[i][j-1] == colors[i][j]) dp[i][j] = Math.max(dp[i][j], dp[i][j-1] + coins[i][j]);
else if(dp[i][j-1] >= k) dp[i][j] = Math.max(dp[i][j], dp[i][j-1] + coins[i][j] - k);
}
ans = Math.max(ans, dp[i][j]);
}
}
System.out.println(ans);
}
}