1038.收集宝藏
Description
有一个n*n的矩阵,矩阵每个格子中都有一些宝藏,从左上角(1, 1)出发,每次只能向下或者向右移动一格,已知每个格子中宝藏的价值,求走到右下角(n, n)时能收集到的宝藏的总最大价值。
Input
第一行为一个整数n(1 <= n <= 1000),表示矩阵的行、列数。
接下来n行,每行n个整数,每个整数表示当前格子的宝藏价值(不超过10000)。
Output
一个整数,表示能收集到的宝藏的最大总价值。
Sample Input
4 1 2 3 10 3 4 1 1 5 2 1 1 1 3 1 1
Sample Output
19
看到这道题,首先想到的是枚举的方法,但是仔细一想,发现如果用枚举的话,结果太复杂,不好设立循环。于是考虑动态分析。
建立动态分析模型
假设最优答案:m【i】【j】
建立原问题与子问题之间的联系:
如果走到【I】【j】的位置,它上一步是【I - 1】【j】或者是【I】【j - 1】
取这两步的最大值,就建立起来联系。
迭代公式建立
m[i][j] = max(m[i-1][j]+a[i][j],m[i][j-1]+a[i][j]);
代码实现
#include <iostream> #include <cstdio> using namespace std; int main() { int n; scanf("%d", &n); static int a[1010][1010] = {0}; for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) scanf("%d", &a[i][j]); static int m[1010][1010] = {0}; m[1][1] = a[1][1]; for(int i = 2; i <= n; i ++) m[i][1] = m[i - 1][1] + a[i][1]; for(int i = 2; i <= n; i ++) m[1][i] = m[1][i - 1] + a[1][i]; for(int i = 2; i <= n; i ++) for(int j = 2; j <= n; j ++) m[i][j] = max(m[i-1][j]+a[i][j],m[i][j-1]+a[i][j]); printf("%d\n", m[n][n]); return 0; }