P1135 奇怪的电梯 题解

Endora ·
更新时间:2024-09-21
· 978 次阅读

博客园同步

原题链接

简要题意:

给定 aia_iai​,求从 AAA 节点走到 BBB 节点的最小步数。若当前在 iii 节点,则可以一步到达 i−aii-a_ii−ai​ 或 i+aii+a_ii+ai​ 节点。(如果不合法则不走)

首先这题肯定是搜索,具体怎么搜因人而异。

因为我比较喜欢朴素的 dfs\texttt{dfs}dfs,因此就说说做法。

显然,如果你打下一个这样的搜索:

inline void dfs(int dep,int bs) { if(depn) return; if(bs==B) {ans=min(ans,bs);return;} dfs(dep+a[dep],bs+1); dfs(dep-a[dep],bs+1); }

你觉得没有任何问题,但是交上去 TLE\texttt{TLE}TLE 了。

给出一组数据 hack\text{hack}hack 掉它:

5 3 4 2 1 2 1 2

然后你的程序彻底陷入死循环了。。。

然后,你机智地说:好,那么我记录上一次的位置,就可以避免重复了!

inline void dfs(int dep,int bs,int last) { if(depn) return; if(bs==B) {ans=min(ans,bs);return;} if(dep+a[dep] != last) dfs(dep+a[dep],bs+1); if(dep-a[dep] != last) dfs(dep-a[dep],bs+1); }

好,交上去还是 TLE\texttt{TLE}TLE 了。

再送你一组数据强力 hack\text{hack}hack:

5 1 5 1 2 1 3 1

然后你的程序就是这样的:

1→2→4→1→2→4→⋯1 \rightarrow 2 \rightarrow 4 \rightarrow1 \rightarrow2 \rightarrow4 \rightarrow \cdots1→2→4→1→2→4→⋯

仍然不行了。

那你说,好,我用一个桶记录走过的步数,不重复走。

然后交上去 WA\texttt{WA}WA 了。再送你两组 hack\text{hack}hack 数据:

假设你的程序优先往下走:

5 3 5 4 1 2 1 2

然后你用 222 步走到终点,发现 1,3,51,3,51,3,5 都走过了,然后咕了。

如果优先向上走:

5 3 1 2 1 2 1 4

这不一样的道理?

那你说,这怎么办?

我:显然记忆化答案!

用 fif_ifi​ 表示 当前 走到第 iii 层的最少步数。

如果当前步数 ≥fi\geq f_i≥fi​ 就可以直接停止。

再做一遍即可。

时间复杂度:O(n)O(n)O(n).

实际得分:90pts90pts90pts.

#pragma GCC optimize(2) #include using namespace std; inline int read(){char ch=getchar();int f=1;while(ch'9') {if(ch=='-') f=-f; ch=getchar();} int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;} int n,A,B,a[201]; int f[201]; inline void dfs(int dep,int bs) { if(depn) return; if(f[dep] && f[dep]<=bs) return; f[dep]=bs; dfs(dep+a[dep],bs+1); dfs(dep-a[dep],bs+1); } int main(){ n=read(),A=read(),B=read(); for(int i=1;i<=n;i++) a[i]=read(); dfs(A,0); if(A!=B && !f[B]) puts("-1"); //走不到 else printf("%d\n",f[B]); //直接走 return 0; }

没有一点点的问题啊? 其实我自己也中了这个坑

那么,最后送你组 hack\text{hack}hack 数据:

5 1 1 0 0 0 0 0

你的程序输出了 111,所以 A=BA=BA=B 的直接处理掉!

实际得分:100pts100pts100pts.

#pragma GCC optimize(2) #include using namespace std; inline int read(){char ch=getchar();int f=1;while(ch'9') {if(ch=='-') f=-f; ch=getchar();} int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;} int n,A,B,a[201]; int f[201]; inline void dfs(int dep,int bs) { if(depn) return; if(f[dep] && f[dep]<=bs) return; f[dep]=bs; dfs(dep+a[dep],bs+1); dfs(dep-a[dep],bs+1); } int main(){ n=read(),A=read(),B=read(); if(A==B) {puts("0");return 0;} for(int i=1;i<=n;i++) a[i]=read(); dfs(A,0); if(!f[B]) puts("-1"); else printf("%d\n",f[B]); return 0; }
作者:bifanwen



电梯 p1

需要 登录 后方可回复, 如果你还没有账号请 注册新账号