一个很重要的条件是从i跳跃到pi,1<=pi<=i,可求出d[i]表示i到i+1走的步数,当再次回到i时直接到i+1。
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#define inf 10000000
#define pi acos(-1.0)
#define eps 1e-8
#define seed 131
using namespace std;
typedef pair<int,int> pii;
typedef unsigned long long ULL;
typedef long long LL;
const int maxn=100005;
int n;
int to[1005];
int vis1[1005];
int vis2[1005];
int g[1005];
int ans=0;
int u;
int mod=1000000007;
int len;
void dfs();
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&to[i]);
memset(vis1,0,sizeof(vis1));
memset(vis2,0,sizeof(vis2));
memset(g,0,sizeof(g));
u=1;
len=0;
dfs();
cout<<ans;
return 0;
}
void dfs()
{
if(u==n+1)
return;
if(vis1[u]==0)
{
vis1[u]=1;
ans++;
ans%=mod;
u=to[u];
dfs();
}
else if(vis2[u]==0)
{
vis2[u]=1;
ans++;
ans%=mod;
g[u]=(ans-len+mod)%mod;
len+=g[u];
len%=mod;
u=u+1;
dfs();
}
else
{
ans=(ans+g[u])%mod;
u=u+1;
dfs();
}
}
用dp做更简洁:
#include<iostream>
#include<string>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<map>
#include<algorithm>
#include<queue>
#include<set>
#define inf 10000000
#define pi acos(-1.0)
#define eps 1e-8
#define seed 131
using namespace std;
typedef pair<int,int> pii;
typedef unsigned long long ULL;
typedef long long LL;
const int maxn=100005;
int mod=1000000007;
int dp[1005];
int p[1005];
int n;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&p[i]);
dp[1]=2;
for(int i=2;i<=n;i++)
{
dp[i]=2;
for(int j=p[i];j<i;j++)
{
dp[i]+=dp[j];
dp[i]%=mod;
}
}
int ans=0;
for(int i=1;i<=n;i++)
{
ans+=dp[i];
ans%=mod;
}
cout<<ans;
return 0;
}