//搜啊搜...
//因为我们每次搜索的起点都是一样的,但是数组的第一个元素不同,所以可以手工算出下一个点,从起点的下一点开始搜
1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "algorithm" 5 using namespace std; 6 __int64 dp[200010][2]; 7 bool vis[200010][2]; 8 int n, ans[200010]; 9 10 __int64 dfs(int x, int chi) 11 { 12 if(x <= 0 || x > n) 13 return 0; 14 if(dp[x][chi]) 15 return dp[x][chi]; 16 if(vis[x][chi]) 17 return dp[x][chi] = -1; 18 vis[x][chi] = 1; 19 __int64 tmp = dfs(x + ((chi)? ans[x]: -ans[x]), chi^1); 20 if(tmp != -1) 21 return dp[x][chi] = ans[x] + tmp; 22 return dp[x][chi] = -1; 23 } 24 25 int main() 26 { 27 int i; 28 scanf("%d", &n); 29 for(i = 2; i <= n; ++i) 30 scanf("%d", &ans[i]); 31 __int64 tmp; 32 vis[1][1] = 1; 33 for(i = 1; i <= n - 1; ++i) { 34 //ans[1] = i; 35 tmp = dfs(1 + i, 0); 36 printf("%I64d ", (tmp != -1)? tmp + i: tmp); 37 } 38 }
//从起点开始搜的话,每次维护一下数组第一个元素的值和起点的出入栈标记就好了
1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "algorithm" 5 using namespace std; 6 __int64 dp[200010][2]; 7 bool vis[200010][2]; 8 int n, ans[200010]; 9 10 __int64 dfs(int x, int chi) 11 { 12 if(x <= 0 || x > n) 13 return 0; 14 if(dp[x][chi]) 15 return dp[x][chi]; 16 if(vis[x][chi]) 17 return dp[x][chi] = -1; 18 vis[x][chi] = 1; 19 __int64 tmp = dfs(x + ((chi)? ans[x]: -ans[x]), chi^1); 20 if(tmp != -1) 21 return dp[x][chi] = ans[x] + tmp; 22 return dp[x][chi] = -1; 23 } 24 25 int main() 26 { 27 int i; 28 scanf("%d", &n); 29 for(i = 2; i <= n; ++i) 30 scanf("%d", &ans[i]); 31 __int64 tmp; 32 for(i = 1; i <= n - 1; ++i) { 33 ans[1] = i; 34 dp[1][1] = vis[1][1] = 0; //确保能够进入搜索起点 35 tmp = dfs(1, 1); 36 printf("%I64d ", tmp); 37 } 38 }