Jumping Haybales (dp)

Jumping Haybales

 

 题意:从左上角到右下角,‘#’不能落脚,每次可以向下或者向右跳小于等于k的距离,问最小需要多少步到达右下角

分析:设dp[i][j]表示到达点坐标点\(i\),\(j\)所需的最少步数,状态见代码

AC_Code:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define endl '\n'
 5 const int maxn=2e3+10;
 6 const int inf=0x3f3f3f3f;
 7 
 8 char s[maxn][maxn];
 9 int n,k;
10 int dp[maxn][maxn];
11 int c[maxn],r[maxn];
12 
13 int main()
14 {
15     scanf("%d%d",&n,&k);
16     for(int i=0;i<n;i++){
17         scanf("%s",s[i]);
18     }
19     if( s[0][0]=='#'){
20         printf("-1\n");
21         return 0;
22     }else if( s[n-1][n-1]=='#'){
23         printf("-1\n");
24         return 0;
25     }
26 
27     memset(dp,inf,sizeof(dp));
28 
29     memset(r,0,sizeof(r));
30     memset(c,0,sizeof(c));
31 
32     dp[0][0]=0;
33 
34     for(int i=0;i<n;i++){
35         for(int j=0;j<n;j++){
36             if( s[i][j]=='#' ) continue;
37             for( ;r[i]<j;r[i]++){
38                 if( s[i][r[i]]=='.' && j-r[i]<=k ) break;//为什么到第一个距离小于k且是点的地方就可以break呢,因为只能往东往南走,后面的小于k且是点的步数到达步数一定是大于等于第一个步数的
39             }
40             dp[i][j]=min(dp[i][j],dp[i][r[i]]+1);
41             for( ;c[j]<i;c[j]++){
42                 if( s[c[j]][j]=='.' && i-c[j]<=k) break;
43             }
44             dp[i][j]=min(dp[i][j],dp[c[j]][j]+1);
45             if( dp[c[j]][j]>=dp[i][j] ) c[j]=i;
46             if( dp[i][r[i]]>=dp[i][j] ) r[i]=j;
47         }
48     }
49 
50     if( dp[n-1][n-1]!=inf ){
51         printf("%d\n",dp[n-1][n-1]);
52     }else{
53         printf("-1\n");
54     }
55 }

 

posted @ 2020-08-04 22:56  swsyya  阅读(189)  评论(0编辑  收藏  举报

回到顶部