蓝桥杯 ADV-62 算法提高 夺宝奇兵

算法提高 夺宝奇兵  

时间限制:1.0s   内存限制:512.0MB

[题目描述]
  在一座山上,有很多很多珠宝,它们散落在山底通往山顶的每条道路上,不同道路上的珠宝的数目也各不相同.下图为一张藏宝地图:

  7
  3 8
  8 1 0
  2 7 4 4
  4 5 2 6 5

  ”夺宝奇兵”从山下出发,到达山顶,如何选路才能得到最多的珠宝呢?在上图所示例子中,按照5->7->8->3->7的顺序,将得到最大值30

[输入]
  第一行正整数N(100>=N>1),表示山的高度
  接下来有N行非负整数,第i行有i个整数(1<=i<=N),表示山的第i层上从左到右每条路上的珠宝数目

[输出]
  一个整数,表示从山底到山顶的所能得到的珠宝的最大数目.
[样例输入]

5 
7 
3  8 
8  1  0  
2  7  4  4 
4  5  2  6  5 

[样例输出]
  30

分析:设f(i, j)为从山顶到第i行第j列之间所能得到的珠宝的最大数目,其递推关系式为

f(i, j) = \begin{cases} \max \{ f(i-1, j-1), f(i-1, j) \} + a_{ij} & \text{ if } 2 \le j \le i-1 \\ f(i-1, j) + a_{ij} & \text{ if } j=1 \\ f(i-1, j-1) + a_{ij} & \text{ if } j=i \end{cases}

初始条件:f(1, 1) = a_{11}

题目要求的就是\max_{1 \le j \le N} \{ f(N, j) \}

#include <stdio.h>

int max(int a, int b)
{
    return a > b ? a : b;
}

int main()
{
    int N;
    int mountain[105][105] = { 0 };
    int f[105][105] = { 0 };

    scanf("%d", &N);
    for (int i = 1; i <= N; ++i)
        for (int j = 1; j <= i; ++j)
            scanf("%d", &mountain[i][j]);

    f[1][1] = mountain[1][1];
    for (int i = 2; i <= N; ++i)
    {
        f[i][1] = f[i-1][1] + mountain[i][1];
        for (int j = 2; j <= i - 1; ++j)
            f[i][j] = max(f[i-1][j-1], f[i-1][j]) + mountain[i][j];
        f[i][i] = f[i-1][i-1] + mountain[i][i];
    }

    int total = f[N][1];
    for (int j = 2; j <= N; ++j)
        total = max(total, f[N][j]);
    printf("%d", total);

    return 0;
}
发布了298 篇原创文章 · 获赞 43 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/liulizhi1996/article/details/104236844