第36次CCF CSP 计算机软件能力认证
这个第四题DP看的人头晕啊  不过总算是看懂了 题目如下

当小 C 在某个状态时,他实际上是“落在”某个格子上,该状态是由上一次跳跃后向后退得到的
假设从某个“出发点” p 进行跳跃,跳跃后落到格子 j,再后退 a[j] 格,最终到达状态 j
即有:状态 = j 且 出发点 = j − a[j]
反过来考虑:若当前状态为 i,则它是由 p = i - a[i] 这个位置发起的跳跃得到的
题目规定:在 p 处(注意 p = i - a[i])最多能往前跳 k[p] 格,即允许跳跃到的原始落点 j 必须满足:j ∈ [p + 1, p + k[p]]
也就是:j ∈ [i − a[i] + 1, i − a[i] + k[i − a[i]]]
简而言之 我如果跳到位置i,那么我的转移应该从i - a[i]开始 这就是最关键的逻辑
同时 如果回退的位置不能到达没有回退的位置处 那么一定不可能走到终点 也就是n位置处
f[i] 表示第一次跳到i位置时所用次数
状态转移如下
    f[1] = 0;
    int R = 1;
    for (int i = 1;i <= n; ++ i) {
        if (f[i] == -1) break;
        for (int j = max(i - a[i] + 1, R + 1);
              j <= min(n, i - a[i] + k[i - a[i]]);
               ++ j) {
            f[j] = f[i] + 1;
            R = j;
        }
    }
将 f[j] 设为 f[i] + 1,表示从状态 i 再跳跃一次可以到达 j
同时更新 R 为 j,以确保下次循环中不会重复更新已处理过的 j\
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号