题目描述: 给你一个从2开始的数组,有两种操作 1:x=x+a[i],y=y+a[i];
2 : x=x-a[i],y=y+a[i];
对于每个i(1<=i<n) 开始时 x=1,y=0,a[1]=i; 然后循环执行1,2 两步操作,直至x<=0||x>n 结束循环输出y值,如果不能结束循环输出 -1;
1<=a[i]<=1e9 2<=n<=2e5;
分析:首先明确一点就是每个点在确定方向后就只有一个值, 那么我可以记住上次查找时该点的值是多少这样我下次找就可以直接用,状态转移可以看成是dp ,然后搜索用dfs记忆化
#include<bits/stdc++.h> using namespace std; int a[200005],vis[200004][2]; long long dp[200005][2]; int n; void dfs(int x,int flag){ if(vis[x][flag]) return ; vis[x][flag]=1; int nex; if(flag) nex=x-a[x]; else nex=x+a[x]; if(nex<=0||nex>n) dp[x][flag]=a[x]; else { dfs(nex,flag^1); if(dp[nex][flag^1]!=-1) dp[x][flag]=dp[nex][flag^1]+a[x]; } } int main(){ ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin>>n; memset(dp,-1,sizeof dp); memset(vis,0,sizeof vis); for(int i=2;i<=n;i++) cin>>a[i]; for(int i=2;i<=n;i++) dfs(i,1); for(int i=2;i<=n;i++) if(dp[i][1]!=-1) cout<<dp[i][1]+i-1<<endl; else cout<<dp[i][1]<<endl; }