考虑到无论往左走还是往下走,下一步又会回来,进而不断在两个格子间来回跳,所以只能往右走或者往下走,并且优先往右走
设 (f[i][j]) 表示走到 ((i,j)) 的最小操作次数,考虑转移
[egin{align}
f[i][j] o f[i][j+1]
\
f[i][j] + [s[i][j+1]='0'] o f[i+1][j]
end{align}
]
暴力转移即可
(我个渣渣场上居然在写 Dijkstra……)
#include <bits/stdc++.h>
using namespace std;
int n,m;
char s[1005][1005];
int f[1005][1005];
void sh(int x,int &y) {
y=min(y,x);
}
signed main() {
cin>>n>>m;
for(int i=1;i<=n;i++) {
cin>>s[i]+1;
}
memset(f,0x3f,sizeof f);
f[1][1]=0;
for(int i=1;i<=n;i++) {
for(int j=1;j<=m;j++) {
if(s[i][j]=='1') continue;
sh(f[i][j],f[i][j+1]);
sh(f[i][j]+(s[i][j+1]=='0'),f[i+1][j]);
}
}
cout<<(f[n][m]>1e7?-1:f[n][m]);
}