zoukankan      html  css  js  c++  java
  • 洛谷P1135奇怪的电梯(正向暴力递归+剪枝优化)

    题目链接:https://www.luogu.org/problemnew/show/P1135

    题目意思很明显,有很多种情况,找到最的方法,也就是最短路。

    看了各种大佬题解,有dfs,bfs搜索做法,floyd,djkstra最短路做法,%%%,这里就只写蒟蒻的深搜做法。。。

    1.MLE,M8个点死循环空间栈超限;没有对走过的点标记,导致还能走回去死循环

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 #include <iomanip>
     5 #include <cstdio>
     6 #include <cstring>
     7 #include <cmath>
     8 using namespace std;
     9 typedef long long ll;
    10 typedef unsigned long long ull;
    11 const int maxn=1005;
    12 int a[maxn];
    13 int vis[maxn][maxn];
    14 int N,A,B;
    15 int ans=1e9;
    16 int p=1;
    17 
    18 void so(int last,int step)
    19 {
    20     //p++;
    21     //if(p>1e4) return;
    22     if(last==B)
    23     {
    24         if(ans>step) ans=step;
    25         return;
    26     }
    27 
    28     int s=last+a[last],x=last-a[last];
    29     if(s<=N) so(s,step+1);
    30     if(x>=1) so(x,step+1);
    31 }
    32 
    33 int main()
    34 {
    35     ios::sync_with_stdio(false); cin.tie(0);
    36 
    37     cin>>N>>A>>B;
    38     for(int i=1;i<=N;i++) cin>>a[i];
    39 
    40     so(A,0);
    41 
    42     if(ans==1e9) cout<<"-1"<<endl;
    43     else cout<<ans<<endl;
    44 
    45     return 0;
    46 }

    2.TLE,标记了但T2个点可以走的路数太多,一条一条走时间太多;
    几乎每条路都是通的,这样更新回来还要重走!
    我试了下最后2点数据,真是跑了好长好长时间才出来答案。。。
    这就对dfs深搜很不利了,这种情况可以考虑剪枝或记忆化(哪个行得通就用哪个,一般剪枝好想把不合题目要求的删掉就行,记忆化不太好想)

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 #include <iomanip>
     5 #include <cstdio>
     6 #include <cstring>
     7 #include <cmath>
     8 using namespace std;
     9 typedef long long ll;
    10 typedef unsigned long long ull;
    11 const int maxn=1e6+5;
    12 int a[maxn];
    13 int vis[maxn];
    14 int N,A,B;
    15 int ans=1e9;
    16 int p=1;
    17 
    18 void so(int last,int step)
    19 {
    20     //cout<<p++<<endl;
    21     if(last==B)
    22     {
    23         if(ans>step) ans=step;
    24         return;
    25     }
    26 
    27     int s=last+a[last],x=last-a[last];
    28     if(s<=N) { if(vis[s]==0) { vis[s]=1; so(s,step+1); vis[s]=0; } }
    29     if(x>=1) { if(vis[x]==0) { vis[x]=1; so(x,step+1); vis[x]=0; } }
    30 }
    31 
    32 int main()
    33 {
    34     ios::sync_with_stdio(false); cin.tie(0);
    35 
    36     cin>>N>>A>>B;
    37     for(int i=1;i<=N;i++) cin>>a[i];
    38 
    39     vis[A]=1;
    40     so(A,0);
    41 
    42     if(ans==1e9) cout<<"-1"<<endl;
    43     else cout<<ans<<endl;
    44 
    45     return 0;
    46 }

    3.优化剪枝50ms过

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 #include <iomanip>
     5 #include <cstdio>
     6 #include <cstring>
     7 #include <cmath>
     8 using namespace std;
     9 typedef long long ll;
    10 typedef unsigned long long ull;
    11 const int maxn=1e6+5;
    12 int a[maxn];
    13 int vis[maxn];
    14 int N,A,B;
    15 int ans=1e9;
    16 int p=1;
    17 
    18 void so(int last,int step)
    19 {
    20     //p++;
    21     //if(p>1e3) return;
    22     if(last==B)
    23     {
    24         //cout<<last<<' '<<step<<endl;
    25         if(ans>step) ans=step;
    26         return;
    27     }
    28 
    29     int s=last+a[last],x=last-a[last];//step<=ans就是剪枝优化...
    30     if(s<=N && vis[s]==0 && step<=ans) { vis[s]=1; so(s,step+1); vis[s]=0; }
    31     if(x>=1 && vis[x]==0 && step<=ans) { vis[x]=1; so(x,step+1); vis[x]=0; }
    32 }
    33 
    34 int main()
    35 {
    36     ios::sync_with_stdio(false); cin.tie(0);
    37 
    38     cin>>N>>A>>B;
    39     for(int i=1;i<=N;i++) cin>>a[i];
    40 
    41     vis[A]=1;
    42     so(A,0);
    43 
    44     if(ans==1e9) cout<<"-1"<<endl;
    45     else cout<<ans<<endl;
    46 
    47     return 0;
    48 }

    4.附带bfs版本27ms过,bfs和dfs遍历搜索所有情况的那种思路是一样的,只不过是以广度优先

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 #include <iomanip>
     5 #include <queue>
     6 #include <cstdio>
     7 #include <cstring>
     8 #include <cmath>
     9 using namespace std;
    10 typedef long long ll;
    11 typedef unsigned long long ull;
    12 const int maxn=1e6+5;
    13 int a[maxn];
    14 int vis[maxn];
    15 int dis[maxn];//bfs,dis数组有记录距离和标记作用!可以代替vis数组
    16 int N,A,B;
    17 queue<int> que;
    18 
    19 void bfs(int sx)
    20 {
    21     dis[sx]=0;
    22     que.push(sx);
    23 
    24     while(que.size())
    25     {
    26         int p=que.front(); que.pop();
    27         if(p==B) break;
    28 
    29         int s=p+a[p],x=p-a[p];
    30         if(s<=N && dis[s]==-1)
    31         {
    32             que.push(s);
    33             dis[s]=dis[p]+1;
    34         }
    35         if(x>=1 && dis[x]==-1)
    36         {
    37             que.push(x);
    38             dis[x]=dis[p]+1;
    39         }
    40     }
    41 }
    42 
    43 int main()
    44 {
    45     ios::sync_with_stdio(false); cin.tie(0);
    46 
    47     cin>>N>>A>>B;
    48     for(int i=1;i<=N;i++) cin>>a[i];
    49     for(int i=0;i<=1005;i++) dis[i]=-1;
    50 
    51     bfs(A);
    52 
    53     cout<<dis[B]<<endl;
    54 
    55     return 0;
    56 }

    加一个记忆化递归版本(额。。不知道哪有问题,只有90分,最后一个毒点WA)

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 #include <iomanip>
     5 #include <cstdio>
     6 #include <cstring>
     7 #include <cmath>
     8 using namespace std;
     9 typedef long long ll;
    10 typedef unsigned long long ull;
    11 const int maxn=1e6+5;
    12 int a[maxn];
    13 int vis[maxn];
    14 int Ans[maxn];
    15 int N,A,B;
    16 int p=1;
    17 
    18 int so(int last)
    19 {
    20     if(Ans[last]!=1e7) return Ans[last];
    21     if(last==B)
    22     {
    23         //cout<<last<<' '<<B<<endl;
    24         return 0;//或者直接返回Ans[last]=0;
    25     }
    26 
    27     int s=last+a[last],x=last-a[last];
    28     int a1=1e7,a2=1e7,ans=1e7;
    29     if(s<=N && vis[s]==0) { vis[s]=1; a1=so(s)+1; vis[s]=0; }
    30     if(x>=1 && vis[x]==0) { vis[x]=1; a2=so(x)+1; vis[x]=0; }
    31 
    32     ans=min(ans,a1);
    33     ans=min(ans,a2);
    34 
    35     Ans[last]=min(Ans[last],ans);
    36     return Ans[last];
    37 
    38 }
    39 
    40 int main()
    41 {
    42     ios::sync_with_stdio(false); cin.tie(0);
    43 
    44     cin>>N>>A>>B;
    45     for(int i=1;i<=N;i++) cin>>a[i];
    46     for(int i=0;i<=1005;i++) Ans[i]=1e7;
    47 
    48     Ans[B]=0;
    49     vis[A]=1;
    50     int ans=so(A);
    51 
    52     if(ans>=1e7) cout<<"-1"<<endl;
    53     else cout<<ans<<endl;
    54 
    55     return 0;
    56 }

    完。

  • 相关阅读:
    软件需求分析——阅读笔记
    第二次冲刺阶段 tenth day
    第16周周总结
    第二次冲刺阶段 ninth day
    判断各种数据类型的方法总结
    vue中8种组件通信方式
    字符串常用方法总结
    JS中轻松遍历对象属性的几种方式
    fetch请求和ajax请求
    js 文件下载,当前页下载,新标签下载____后端返回 GET/POST 文件流,下载文件
  • 原文地址:https://www.cnblogs.com/redblackk/p/9821194.html
Copyright © 2011-2022 走看看