ZJ1 附加题
思路:暴力模拟超时!动态规划通过!dp[i]表示第一次到达i需要移动次数!1<=pi<=i即策略B只会倒退,如果使用策略A前进到达i房间只会到达i-1房间偶数次+1!那么递推公式为dp[i]=(dp[i-1]+1+dp[i-1]-dp[arr[i-2]]+1)% MOD!即第一次到达dp[i-1]移动一次到arr[i-2]再从arr[i-2]到i-1再移动一步到i!同时注意由于存在减法故可能会出现负数!那么最后还需要根据dp[n+1]正负(dp[n+1]<0)?dp[n+1]+MOD:dp[n+1]!
// 暴力模拟 超时
const rl = require("readline").createInterface({ input: process.stdin })
var iter = rl[Symbol.asyncIterator]()
const readline = async () => (await iter.next()).value
void async function () {
// 取模
let MOD=1e9+7
// 获取房间数
let n = parseInt((await readline()).trim())
// 获取策略
let arr = (await readline()).trim().split(/\s+/).map(Number)
// dp数组
let dp=Array(n+1).fill(0)
// dp[1] 初始化为1
let i = 1
// 记录次数
let res = 0
while(i!==(n+1))
{
// 访问次数加一
dp[i]++
res++
// 根据奇偶性判断
if(dp[i]%2==0)
i++
else
i=arr[i]
}
console.log(res%MOD)
}()
// 动态规划 通过
const rl = require("readline").createInterface({ input: process.stdin })
var iter = rl[Symbol.asyncIterator]()
const readline = async () => (await iter.next()).value
void async function () {
// 取模
let MOD=1e9+7
// 获取房间数
let n = parseInt((await readline()).trim())
// 获取策略 注意arr有效数据从0开始 dp有效数据从1开始
let arr = (await readline()).trim().split(/\s+/).map(Number)
// dp数组 dp[i]表示第一次到达i需要移动次数
let dp=Array(n+2).fill(0)
// 1<=pi<=i 只会倒退 前进到达i房间只会到达i-1房间偶数次+1
for(let i=2;i<=n+1;i++)
{
// 第一次到达dp[i-1]移动一次到arr[i-2]再从arr[i-2]到i-1再一步i
dp[i]=(dp[i-1]+1+dp[i-1]-dp[arr[i-2]]+1)%MOD
}
console.log((dp[n+1]<0)?dp[n+1]+MOD:dp[n+1])
}()

