• 计蒜客 动态规划基础 逃生


    题目:

    蒜头君在玩一款逃生的游戏。在一个 n×m 的矩形地图上,蒜头位于其中一个点。地图上每个格子有加血的药剂,和掉血的火焰,药剂的药效不同,火焰的大小也不同,每个格子上有一个数字,如果格子上的数字是正数说明是一个药剂代表增加的生命值,如果是负数说明是火焰代表失去的生命值。
    蒜头初始化有 v 点血量,他的血量上限是 c,任何时刻他的生命值都不能大于血量上限,如果血量为 0 则会死亡,不能继续游戏。
    矩形地图上的四个角(1,1),(1,m),(n,1),(n,m)为游戏的出口。游戏中只要选定了一个出口,就必须朝着这个方向走。例如,选择了左下的出口,就只能往左和下两个方向前进,选择了右上的出口,就只能往右和上两个方向前进,左上和右下方向的出口同理。
    如果成功逃生,那么剩余生命值越高,则游戏分数越高。为了能拿到最高分,请你帮忙计算如果成功逃生最多能剩余多少血量,如果不能逃生输出 −1-1−1。

    输入格式

    第一行依次输入整数 n,m,x,y,v,c(1<n,m≤1000,1≤x≤n,1≤y≤m,1≤v≤c≤10000), 其中 n,m 代表地图大小,(x,y) 代表蒜头君的初始位置,v 代表蒜头的初始化血量,c 代表蒜头的生命值上限。
    接下来 nnn 行,每行有 m 个数字,代表地图信息。(每个数字的绝对值不大于100,地图中蒜头君的初始位置的值一定为 0)

    输出格式

    一行输出一个数字,代表成功逃生最多剩余的血量,如果失败输出 −1。

    样例输入

    4 4 3 2 5 10
    1 2 3 4
    -1 -2 -3 -4
    4 0 2 1
    -4 -3 -2 -1

    样例输出

    10
     

    思路:

    首先遇到一个问题,起点并非在图的某一个角上,而是在图中任意一点。所以要做的就是四个方向上的四次求解。
    每个循环当中的核心内容有几点要注意:
    1. 如果是原点,跳过,原点不处理。
    2. 如果在同行同列也要单独处理,因为可能会导致这个点的数值来自不是这个方向上的区域。
    3. 如果人的生命值已经≤0,后来再变正,也没有意义,因为人已经死过了。所以可以处理为,如果人死了,就把他的生命值赋值为无限小。
    4. 如果人的生命值大于最大生命值,生命值维持在最大生命值。

    程序:

      1 #include <iostream>
      2 #include <cstdlib>
      3 #include <cstring>
      4 #include <cmath>
      5 using namespace std;
      6 int n,m,x,y,v,c,map[1005][1005],f[1005][1005],dead[1005][1005];
      7 void p()
      8 {
      9     for (int i=1; i<=n; i++)
     10     {
     11         for (int j=1; j<=m; j++)
     12         {
     13             cout << f[i][j] << " ";
     14         }
     15         cout << endl;
     16     }
     17     cout << endl;
     18 }
     19 int main()
     20 {
     21     cin >> n >> m >> x >> y >> v >> c;
     22     for (int i=1; i<=n; i++)
     23     {
     24         for (int j=1; j<=m; j++)
     25         {
     26             cin >> map[i][j];
     27         }
     28     }
     29     memset(f,0,sizeof(f));
     30     memset(dead,0,sizeof(f));
     31     f[x][y] = v;
     32     //左上 
     33     for (int i=x; i>=1; i--)
     34     {
     35         for (int j=y; j>=1; j--)
     36         {
     37             if (i==x && j==y)
     38                 continue;
     39             else if (i==x)
     40                 f[i][j] = f[i][j+1]+map[i][j];
     41             else if (j==y)
     42                 f[i][j] = f[i+1][j]+map[i][j];
     43             else
     44                 f[i][j] = max(f[i+1][j],f[i][j+1])+map[i][j];
     45             if (f[i][j]<=0)
     46                 f[i][j] = -10000000;
     47             if (f[i][j]>c)
     48                 f[i][j] = c;
     49         }
     50     }
     51     //右下 
     52     for (int i=x; i<=n; i++)
     53     {
     54         for (int j=y; j<=m; j++)
     55         {
     56             if (i==x && j==y)
     57                 continue;
     58             else if (i==x)
     59                 f[i][j] = f[i][j-1]+map[i][j];
     60             else if (j==y)
     61                 f[i][j] = f[i-1][j]+map[i][j];
     62             else
     63                 f[i][j] = max(f[i-1][j],f[i][j-1])+map[i][j];
     64             if (f[i][j]<=0)
     65                 f[i][j] = -10000000;
     66             if (f[i][j]>c)
     67                 f[i][j] = c;
     68         }
     69     }
     70     //左下 
     71     for (int i=x; i<=n; i++)
     72     {
     73         for (int j=y; j>=1; j--)
     74         {
     75             if (i==x && j==y)
     76                 continue;
     77             else if (i==x)
     78                 f[i][j] = f[i][j+1]+map[i][j];
     79             else if (j==y)
     80                 f[i][j] = f[i-1][j]+map[i][j];
     81             else
     82                 f[i][j] = max(f[i-1][j],f[i][j+1])+map[i][j];
     83             if (f[i][j]<=0)
     84                 f[i][j] = -10000000;
     85             if (f[i][j]>c)
     86                 f[i][j] = c;
     87         }
     88     }
     89     for (int i=x; i>=1; i--)
     90     {
     91         for (int j=y; j<=m; j++)
     92         {
     93             if (i==x && j==y)
     94                 continue;
     95             else if (i==x)
     96                 f[i][j] = f[i][j-1]+map[i][j];
     97             else if (j==y)
     98                 f[i][j] = f[i+1][j]+map[i][j];
     99             else
    100                 f[i][j] = max(f[i+1][j],f[i][j-1])+map[i][j];
    101             if (f[i][j]<=0)
    102                 f[i][j] = -10000000;
    103             if (f[i][j]>c)
    104                 f[i][j] = c;
    105         }
    106     }
    107     if (max(max(f[1][1], f[n][m]), max(f[1][m], f[n][1]))<0)
    108         cout << -1 << endl;
    109     else
    110         cout << max(max(f[1][1], f[n][m]), max(f[1][m], f[n][1])) << endl;
    111     return 0;
    112 }
  • 相关阅读:
    openmp
    opencv 读写矩阵
    string to const char*
    c++ string to number
    HDU 1520 Anniversary Party
    ZOJ 1003 Crashing Balloon
    HDU 4171 Paper Route
    ZOJ 2067 White Rectangles
    TOJ 1690 Cow Sorting (置换群)
    TOJ 2814 Light Bulb
  • 原文地址:https://www.cnblogs.com/OIerPrime/p/7674558.html
Copyright © 2020-2023  润新知