CF407B 「Long Path」
CF407B 「Long Path」
星影落九天,鱼雁舞千弦。但为君沉吟,落日天涯圆。
题目描述
有个人进入一个迷宫,这个迷宫共有\(n+1\)个房间,编号从\(1\)~\(n+1\),ta现在在第1个房间,需要到达第\(n+1\)个房间以出去。房间\(i\)有两个前进的门(来时的门不算),第一扇门通向第\(i+1\)个房间,第二扇门通向第
\(p_i(1<=p_i<=i)\)房间,为了不迷路,这个人每到达一个房间,就会给这个房间画一个标记,画完后如果这个房间的标记数为偶数个,ta就会选择这个房间第一扇门前进,否则选择第二扇门前进。 求这个人需要通过多少道门到达终点(即第\(n+1\)个房间),答案对\(1000000007\)取模)
思路:
注意到从\(i\)走到\(i+1\)的过程,应该是\(i\to p_i\to i\to i+1\)
那么我们用\(dp_{i+1}\)表示从第一个房间第一次到第\(i+1\)个房间所穿过的门的数量
根据上面的流程图,显然有:\(dp_{i+1}=dp_i+1+dp_i-dp_{p_i}+1\)
解释递推式:
\(dp_i+1\):第一次到第\(i\)个房间再到第\(p_i\)个房间所经过门的数量
\(dp_i-dp_{p_i}+1\):从第\(p_i\)房间又跳回\(i\)并且走到(第一次)\(i+1\)房间所经过的门的数量
这样就可以得到上面的递推式啦~
为各位大佬献上我丑陋的代码~
#include<bits/stdc++.h>
#define prf printf
#define scf scanf
#define ll long long
using namespace std;
const ll N=1000000+100,M=1000000007;
ll n,a[N],num[N],F[N];
ll read()
{
ll x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main()
{
n=read();
for(int i=1;i<=n;i++)a[i]=read();
for(int i=1;i<=n;i++)
F[i+1]=(F[i]*2)%M-F[a[i]]+2,F[i+1]=(F[i+1]+M)%M;//记得这里一定要先加上模数再模一次,因为算出来的值可能为负数
printf("%lld\n",F[n+1]);
return 0;
}