题意:一共n+1个房间,一个人从1走到n+1,如果第奇数次走到房间i,会退回到房间Pi,如果偶数次走到房间i,则走到房间i+1,问走到n+1需要多少步,结果对1e9+7取模。
题解:设dp[i]表示从1走到i需要多少步,那么走到房间i+1需要dp[i+1]=dp[i]+1+x+1,这里面第一个1表示走完这步退回到Pi,这个x表示退回到房间Pi再走回来的步数,第二个1表示走完这步到达i+1。我们发现:1.当走到房间Pi的时候,Pi+1到i都是没有走过的即为0次;2.当走到房间i的时候,Pi+1到i这段一定都走过了偶数次,因为奇数次是不会放你过来的,一定都是偶数次才能走到i这步,所以说状态相同。x就是从Pi走到i所需要的步数,那么x=dp[i]-dp[p[i]],所以状态转移方程是dp[i+1]=dp[i]+1+dp[i]-dp[p[i]]+1。值得注意在结果对1e9+7取模,取模的时候要先+mod再%mod,其中涉及到减法可能有负数,前面每个数都是取模过的数,dp[i]是很可能小于dp[p[i]]的,当然如果都不取模的话dp数组肯定是递增的。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn=1005; const ll mod=1e9+7; ll p[maxn],dp[maxn]; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld",&p[i]); dp[1]=0; for(int i=1;i<=n;i++) dp[i+1]=(dp[i]+1+dp[i]-dp[p[i]]+1+mod)%mod; printf("%lld ",dp[n+1]); return 0; }