试题 算法训练 拿金币
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
有一个N x N的方格,每一个格子都有一些金币,只要站在格子里就能拿到里面的金币。你站在最左上角的格子里,每次可以从一个格子走到它右边或下边的格子里。请问如何走才能拿到最多的金币。
输入格式
第一行输入一个正整数n。
以下n行描述该方格。金币数保证是不超过1000的正整数。
输出格式
最多能拿金币数量。
样例输入
3
1 3 3
2 2 2
3 1 2
样例输出
11
数据规模和约定
n < = 1000 n<=1000 n<=1000
题解
这是一道十分简单的dp模板题,走到
(
i
,
j
)
(i,j)
(i,j)时能获得的最大金币数是走到
(
i
−
1
,
j
)
(i-1,j)
(i−1,j)和
(
i
,
j
−
1
)
(i,j-1)
(i,j−1)这两个地方最大金币的最大值加上当前所在坐标的金币值,所以可以轻松得到递推公式:
d
p
[
i
]
[
j
]
=
c
o
i
n
s
[
i
]
[
j
]
+
m
a
x
(
d
p
[
i
]
[
j
−
1
]
,
d
p
[
i
−
1
]
[
j
]
)
dp[i][j] = coins[i][j]+max(dp[i][j-1],dp[i-1][j])
dp[i][j]=coins[i][j]+max(dp[i][j−1],dp[i−1][j])
题目答案显而易见
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
* @author 王宇哲
*/
public class Main {
public static void main(String[] args) throws Exception{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(reader.readLine());
int[][] coins = new int[n+1][n+1];
String[] tmp;
for(int i= 1;i<=n;i++){
tmp = reader.readLine().split(" ");
for(int j=1;j<=n;j++){
coins[i][j] = Integer.parseInt(tmp[j-1]);
}
}
int[][] dp = new int[n+1][n+1];
dp[1][1] = coins[1][1];
for(int i=1 ;i<=n;i++){
for(int j=1;j<=n;j++){
dp[i][j] = coins[i][j] +Math.max(dp[i-1][j],dp[i][j-1]);
}
}
System.out.println(dp[n][n]);
}
}