題目鏈結
有乙個n∗m迷宮,迷宮中每個格仔用0或1表示,0表示該格仔可以通過,1表示該格仔是個障礙物,牛妹站在格仔(1,1),出口在格仔(n,m),牛妹想要走出迷宮,但牛妹只會按以下策略走:
牛妹當前所在的格仔稱為當前格仔
1.如果當前格仔右邊沒有障礙物,牛妹就向右走,否則轉到2。
2.如果當前格仔下方沒有障礙物,牛妹就向下走,否則轉到3。
3.如果當前格仔左邊沒有障礙物,牛妹就向左走,否則轉到4。
4.如果當前格仔上方沒有障礙物,牛妹就向上走,否則轉到5。
5.牛妹站在原地不動。
由於牛妹按這樣的策略可能會無法走到出口,牛妹的好朋友牛牛決定在牛妹離開格仔(1,1)前把迷宮中的一些非障礙格仔變成障礙,幫助牛妹走出迷宮,但是牛牛比較懶,他想要最小化變成障礙的非障礙格仔的數量。
第一行兩個整數n,m表示迷宮的大小
接下來n行每行乙個長度為m的01串表示迷宮的格局
輸出乙個整數表示牛牛最少需要轉換成障礙格仔的非障礙格仔的數量,如果無法幫助牛妹走出迷宮,輸出−1。
4 4
0000
0110
0110
0000
0
比賽時一直想不到好的做法,看了題解才發現是簡單dp,牛妹不可能往左或往上走,那麼就按以下策略dp即可:
1.向右走,dp[
i][j
+1]=
min(
dp[i
][j+
1],d
p[i]
[j])
dp[i][j+1]=min(dp[i][j+1],dp[i][j])
dp[i][
j+1]
=min
(dp[
i][j
+1],
dp[i
][j]
)2.向下走,若 a[i
+1][
j]=1
,dp[
i+1]
[j]=
min(
dp[i
+1][
j],d
p[i]
[j])
;若a[
i+1]
[j]=
0,dp
[i+1
][j]
=min
(dp[
i+1]
[j],
dp[i
][j]
+1
)a[i+1][j]=1,dp[i+1][j]=min(dp[i+1][j],dp[i][j]);若a[i+1][j]=0,dp[i+1][j]=min(dp[i+1][j],dp[i][j]+1)
a[i+1]
[j]=
1,dp
[i+1
][j]
=min
(dp[
i+1]
[j],
dp[i
][j]
);若a
[i+1
][j]
=0,d
p[i+
1][j
]=mi
n(dp
[i+1
][j]
,dp[
i][j
]+1)
ac**如下:
#include
#define inf 0x3f3f3f3f
using
namespace std;
typedef
long
long ll;
const
int n=
1e3+5;
int n,m,dp[n]
[n];
char s[n]
[n];
intmain()
}fill
(dp[0]
,dp[0]
+n*n,inf)
; dp[0]
[0]=
0;for(
int i=
0;i}}
if(dp[n-1]
[m-1
]==inf)
printf
("-1\n");
else
printf
("%d\n"
,dp[n-1]
[m-1])
;}
牛客練習賽58 D 迷宮
乙個n m迷宮,迷宮中每個格仔用0或1表示,0表示該格仔可以通過,1表示該格仔是個障礙物,牛妹站在格仔 1,1 出口在格仔 n,m 牛妹想要走出迷宮,但牛妹只會按以下策略走 牛妹當前所在的格仔稱為當前格仔 如果當前格仔右邊沒有障礙物,牛妹就向右走,否則轉到2。如果當前格仔下方沒有障礙物,牛妹就向下走...
牛客練習賽58 D 迷宮 dp
考慮到無論往左走還是往下走,下一步又會回來,進而不斷在兩個格仔間來回跳,所以只能往右走或者往下走,並且優先往右走 設 f i j 表示走到 i,j 的最小操作次數,考慮轉移 begin f i j to f i j 1 f i j s i j 1 0 to f i 1 j end 暴力轉移即可 我個...
牛客練習賽58
a 給你兩個序列ai,bia i,b i ai bi 然後讓你兩兩配對相加,使得最大值最小。貪心。乙個從大到小排,乙個從小到大排,直接相加。b給你乙個01字串,然後讓你找到最多的組,滿足每一組都有0和1。貪心。從前往後掃。遇到0和1是立馬累加,思路 一開始想得是每次挑出行和列中的最大值,然後累加,沒...