Codeforces Round #174 (Div. 1) B. Cow Program(动态规划+记忆化搜索)

 

题目大意

 

Farmer John 给了他的 cows 一个程序玩。这个程序有两个整形变量 x 和 y,并且在一个正数序列 a1 a2 a3,...,an (2≤n≤2*105,1≤ai≤109)中执行以下操作:

        1、初始化 x=1, y=0,如果经过任何步骤之后 x≤0 或者 x>n,程序立刻停止运行

        2、x 和 y 同时增加 ax(注意:增加的值是 a 序列中的第 x 个,也就是 ax

        3、x 减小 ax,y 增加 ax

        4、程序重复执行步骤 2 和步骤 3 直至终止

现在给了你 a2 a3 a4,...,an,程序总共运行了 n-1 次,第 i(1≤i≤n-1) 次运行的时候 a1=i,问程序停止运行之后 y 是多少?如果不能停止运行,输出 -1

 

做法分析

 

观察步骤 2 和步骤 3,可以知道:

        1、y 是记录的 x 变化的值,程序终止只和 x 有关,与 y 无关

        2、步骤 2 使得 x 增加,步骤 3 使得 x 减小

        3、当 x 为 1 的时候,下一步必然是执行步骤 2(因为上面的第 2 条规律),永远不可能停止,输出 -1

        4、当 x 表示的值重复出现并且下一步执行的步骤相同时,程序必然陷入一个循环中,永远不可能停止,输出 -1

想到了上面的四个规律,这道题目就简单了

定义 f(i, j) 表示:当 x=i 的时候,到程序终止,y 会加上的值是多少,那么,状态就是这样转移的:

        f(i, 0)=f(i+ai, 1)+ai:这一步该执行步骤 2

        f(i, 1)=f(i-ai, 0)+ai:这一步该执行步骤 3

在计算的过程中,如果 i+ai 或者 i-ai 超过范围,必然是程序终止了;如果 i=1 或者 i 是之前某个经过的节点,必然陷入死循环

那么每次 a1 变化的时候,直接输出 a1+f(1+a1, 1) 就行了 

 

参考代码

 

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 
 5 using namespace std;
 6 
 7 typedef long long LL;
 8 const int N=200006;
 9 const LL INF=((1LL)<<60);
10 
11 LL f[N][2];
12 bool vs[N][2];
13 int n, A[N];
14 
15 LL DP(int x, int dir)
16 {
17     if(x>n || x<=0) return 0;
18     if(x==1) return INF;
19     if(f[x][dir]!=-1) return f[x][dir];
20     if(vs[x][dir]) return INF;
21     vs[x][dir]=1;
22     LL res;
23     if(dir==0) res=DP(x+A[x], 1);
24     else res=DP(x-A[x], 0);
25     if(res!=INF) f[x][dir]=(LL)A[x]+res;
26     else f[x][dir]=INF;
27     return f[x][dir];
28 }
29 
30 int main()
31 {
32     scanf("%d", &n);
33     for(int i=2; i<=n; i++) scanf("%d", &A[i]);
34     memset(f, -1, sizeof f);
35     memset(vs, 0, sizeof vs);
36     for(int i=2; i<=n; i++)
37     {
38         if(f[i][0]==-1) f[i][0]=DP(i, 0);
39         if(f[i][1]==-1) f[i][1]=DP(i, 1);
40     }
41     for(int i=1; i<n; i++)
42     {
43         if(f[1+i][1]==INF) printf("-1\n");
44         else printf("%I64d\n", i+f[1+i][1]);
45     }
46     return 0;
47 }
B. Cow Program

 

题目链接 & AC通道

 

Codeforces Round #174 (Div. 1) B. Cow Program

 

 

 

posted @ 2013-05-16 19:24  jianzhang.zj  阅读(399)  评论(0编辑  收藏  举报