看到题意要模100000007时就知道这个题要么有规律,要么用DP做,注意到1<=p[i]<=i,判断这道题可以用DP。
我们用f[i]表示第一次走到该点时所用的步数,由于1<=p[i]<=i知道i点一定是从i-1点走过来的。当第一次走到i-1点时i-1点有一个标记此时花费时间为f[i-1],要走一步返回p[i-1]点,然后从p[i-1]点走到i-1点花费的时间为f[i-1]-f[p[i-1]],再走一步走到第i点。那么我们可以得到f[i]=2*f[i-1]-f[p[i-1]]+2,记得对1000000007取模。
一个值得注意的地方是:由于DP方程中有减法操作,所以最后得到的结果可能是负数,此时,我们要将它加上若干个1000000007使其变成正数。
#include <cstdio>
#include <iostream>
using namespace std;
#define MOD 1000000007
int n,p[1005];
long long f[1005];
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&p[i]);
f[1]=0;
for (int i=2;i<=n+1;i++) f[i]=(2*f[i-1]-f[p[i-1]]+2)%MOD;
while (f[n+1]<0) f[n+1]+=MOD;
printf("%d\n",f[n+1]);
return 0;
}