C6-危机合约

题目描述

一天起床,你突然发现自己成为了整合运动的一员,作为火刀哥的手下前去探路。由于危机合约的特殊性,博士只能布置没有阻挡数的干员,每路过一个干员就会受到一次他的攻击,你的目的就是在不被干掉的情况下,从位于最左第一列某点的红色出生点走到位于最右某点的蓝色目的地。作为一个普通宿主士兵,你只能走向右上,右,右下三个格子。

输入

第一行n和m,表示地图有n行m列 (n,m<100)

第二行h,a和b,h表示你现有的血量,红色出生点在第0列a行,蓝色目的地在第m+1列b行(1<=a,b<=n)

接下来n行,每行m列,其中'*'表示这个点不能走,数字表示这个点上干员对你的伤害,范围0到9

输出

如果能够走到目的地,则输出剩余血量

如果已经死亡,则输出"doctor win"

输入样例

3 5
20 1 3
0 1 2 * 4
2 3 * 3 5
6 1 2 * 4

输出样例

10

样例解释

Q9zkGV.md.jpg

核心思想

动态规划递推式

  dp[i][j] = min(min(dp[i-1][j],dp[i-1][j-1]),dp[i-1][j+1]) + f[j][i]; 

初始化边界防止走出去

  memset(dp,0x3f,sizeof(dp));

开始点置0

  dp[0][a] = 0;

代码

#include <iostream>
#include <string.h>
#include<stdio.h>
using namespace std;
int f[105][105];
int dp[105][105];
int main()
{
    int h,a,b;
    int n,m;
    cin>>n>>m;
    cin>>h>>a>>b;
    memset(dp,0x3f,sizeof(dp));
    dp[0][a] = 0;
    for(int i = 1; i<= n; i++)
    {
        for(int j = 1; j<= m; j++)
        {
            char q;
            cin>>q;
            if(q == '*')
                f[i][j] = 0x3f3f3f3f;
            else
                f[i][j] = q - '0';
        }
    }

    for(int i = 1; i<= m; i++)
    {
        for(int j = 1; j<= n; j++)
        {
            dp[i][j] = min(min(dp[i-1][j],dp[i-1][j-1]),dp[i-1][j+1]) + f[j][i];
        }
    }
    int ans = h - min(min(dp[m][b],dp[m][b-1]),dp[m][b+1]);
    if(ans > 0)
        cout<<ans<<endl;
    else
        cout<<"doctor win"<<endl;
    return 0;
}
原文地址:https://www.cnblogs.com/kubab119/p/11930547.html