CF407B 「Long Path」

CF407B 「Long Path」

星影落九天,鱼雁舞千弦。但为君沉吟,落日天涯圆。

[题目传送门](洛谷)

题目描述

有个人进入一个迷宫,这个迷宫共有 n + 1 n+1 n+1个房间,编号从 1 1 1~ n + 1 n+1 n+1,ta现在在第1个房间,需要到达第 n + 1 n+1 n+1个房间以出去。房间 i i i有两个前进的门(来时的门不算),第一扇门通向第 i + 1 i+1 i+1个房间,第二扇门通向第
p i ( 1 < = p i < = i ) p_i(1<=p_i<=i) pi(1<=pi<=i)房间,为了不迷路,这个人每到达一个房间,就会给这个房间画一个标记,画完后如果这个房间的标记数为偶数个,ta就会选择这个房间第一扇门前进,否则选择第二扇门前进。 求这个人需要通过多少道门到达终点(即第 n + 1 n+1 n+1个房间),答案对 1000000007 1000000007 1000000007取模)

思路:

注意到从 i i i走到 i + 1 i+1 i+1的过程,应该是 i → p i → i → i + 1 i\to p_i\to i\to i+1 ipiii+1

那么我们用 d p i + 1 dp_{i+1} dpi+1表示从第一个房间第一次到第 i + 1 i+1 i+1个房间所穿过的门的数量

根据上面的流程图,显然有 d p i + 1 = d p i + 1 + d p i − d p p i + 1 dp_{i+1}=dp_i+1+dp_i-dp_{p_i}+1 dpi+1=dpi+1+dpidppi+1

解释递推式:

d p i + 1 dp_i+1 dpi+1:第一次到第 i i i个房间再到第 p i p_i pi个房间所经过门的数量

d p i − d p p i + 1 dp_i-dp_{p_i}+1 dpidppi+1:从第 p i p_i pi房间又跳回 i i i并且走到(第一次) i + 1 i+1 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;	
	
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值