sdnu 1038 收集宝藏(动态分析)

解决一个n*n矩阵中的宝藏收集问题,从左上角出发,仅能向下或向右移动,求到达右下角时能收集的最大宝藏价值。通过动态规划算法建立模型并给出代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1038.收集宝藏

Time Limit: 1500 MS    Memory Limit: 32768 KB
Total Submission(s): 247    Accepted Submission(s): 120

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值