题意:
给出n层楼的灯的状态,要关闭所有的灯,问最少走多少步。
思路:
dp[i][0] 表示从左边上,dp[i][1]表示从右边上。
注意点:
- 楼梯在第一列和最后一列
- 每次上需要加1
- 对l和r的处理需要谨慎
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn = 105;
const int INF = 0x3f3f3f3f;
int n,m;
char str[maxn][maxn];
int dp[maxn][2];
int vis[maxn];
int l[maxn],r[maxn];
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
for(int i = n;i >= 1; i--) {
scanf("%s",str[i]);
l[i] = m+1;
r[i] = 0;
for(int j=0;j<m+2;j++) {
if(str[i][j]=='1') {
vis[i] = true;
r[i] = max(j,r[i]);
l[i] = min(j,l[i]);
}
}
}
for(int i=n;i>=1;i--) {
l[i] = m - l[i] + 1;
}
int x = n;
while(!vis[x--] && x > 0) n--;
if(n == 1) {
printf("%d\n",r[1]);
return 0;
}
memset(dp,INF,sizeof(dp));
dp[1][0] = 2*r[1]+1;
dp[1][1] = m+2;
for(int i = 2;i < n; i++) {
dp[i][0] = min(dp[i-1][0]+2*r[i],dp[i-1][1]+m+1) + 1;
dp[i][1] = min(dp[i-1][0]+m+1,dp[i-1][1]+2*l[i]) + 1;
}
int ans = min(dp[n-1][1]+l[n],dp[n-1][0]+r[n]);
printf("%d\n",ans);
return 0;
}