P1902 刺杀大使——洛谷(疑问)2024.1.28

题目描述

某组织正在策划一起对某大使的刺杀行动。他们来到了使馆,准备完成此次刺杀,要进入使馆首先必须通过使馆前的防御迷阵。

迷阵由 �×�n×m 个相同的小房间组成,每个房间与相邻四个房间之间有门可通行。在第 �n 行的 �m 个房间里有 �m 个机关,这些机关必须全部打开才可以进入大使馆。而第 11 行的 �m 个房间有 �m 扇向外打开的门,是迷阵的入口。除了第 11 行和第 �n 行的房间外,每个房间都被使馆的安保人员安装了激光杀伤装置,将会对进入房间的人造成一定的伤害。第 �i 行第 �j 列 造成的伤害值为 ��,�pi,j​(第 11 行和第 �n 行的 �p 值全部为 00)。

现在某组织打算以最小伤害代价进入迷阵,打开全部机关,显然,他们可以选 择任意多的人从任意的门进入,但必须到达第 �n 行的每个房间。一个士兵受到的伤害值为他到达某个机关的路径上所有房间的伤害值中的最大值,整个部队受到的伤害值为所有士兵的伤害值中的最大值。现在,这个恐怖组织掌握了迷阵的情况,他们需要提前知道怎么安排士兵的行进路线可以使得整个部队的伤害值最小。

输入格式

第一行有两个整数 �,�n,m,表示迷阵的大小。

接下来 �n 行,每行 �m 个数,第 �i 行第 �j 列的数表示 ��,�pi,j​。

输出格式

输出一个数,表示最小伤害代价。

输入输出样例

输入 #1复制

4 2
0 0 
3 5 
2 4 
0 0 

输出 #1复制

3

说明/提示

  • 50%50% 的数据,�,�≤100n,m≤100;
  • 100%100% 的数据,�,�≤1000n,m≤1000,��,�≤1000pi,j​≤1000

想法:

我看到就想用dfs了,然后一直在想Max的值(这条路线的最大伤害值)怎么弄,因为dfs是一条路走到黑,然后再回溯到上一个结点,那Max的值就可能会改变,因为不同路线伤害值的最大值可能不同。后来我想,既然状态数组st用来可以用来表示回溯(dfs后重置st数组为0),那我也可以在回溯后更新一下Max的值。所以有了如下代码,样例也是通过的,不过不知到不考虑时间限制的话有没有问题,因为这个答案全超时了QAQ。我看到也有人用dfs写,结合二分。但我还不知道怎么想到二分的。也有用bfs的,我bfs也不太会用,也还想不到怎么用bfs。

代码:

#include<bits/stdc++.h>
using namespace std;
int n,m;
int fj[1010][1010];
int st[1010][1010];
int dx[]={0,0,-1,1};
int dy[]={1,-1,0,0};
int ans=0x3f3f3f3f,Max=0;
void dfs(int x,int y){
    if(x==n) return ;
    for(int i=0;i<4;i++){
        int xx=dx[i]+x;
        int yy=dy[i]+y;
        if(xx>n||xx<1||yy>m||yy<1) continue;
        if(st[xx][yy]) continue;
        st[xx][yy]=1;
        Max=Max>fj[xx][yy]?Max:fj[xx][yy];
        if(xx==n){
            //if(Max!=0)
                ans=ans<Max?ans:Max;
            //Max=0;
        }
        dfs(xx,yy);
        st[xx][yy]=0;
        Max=0;
        for(int j=1;j<=n;j++){
            for(int k=1;k<=m;k++){
                if(st[j][k]==1&&fj[j][k]>Max)
                    Max=fj[j][k];
            }
        }
    }
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
            cin>>fj[i][j];
    }
    st[1][1]=1;
    dfs(1,1);
    cout<<ans;
}

  • 15
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值