JZOJ1422.2017.03.25【NOIP 普及组】模拟赛C组 T4步行

题目描述

ftiasch 又开发了一个奇怪的游戏,这个游戏是这样的:有N 个格子排成一列,每个格子上有一个数

字,第i 个格子的数字记为Ai。这个游戏有2 种操作:

  1. 如果现在在第i 个格子,则可以跳到第Ai 个格子。

  2. 把某个Ai 增加或减少1。

nm 开始在第1 个格子,他需要走到第N 个格子才能通关。现在他已经头昏脑涨啦,需要你帮助他

求出,从起点到终点最少需要多少次操作。

输入

第1 行,1 个整数N。第2 行,N 个整数Ai。

输出

第1 行,1 个整数,表示最少的操作次数。

样例输入

5

3 4 2 5 3

样例输出

3

数据范围限制

提示

数据范围

• 对于30% 的数据,1<=  N <=  10。

• 对于60% 的数据,1<=   N <=  1 000。

• 对于100% 的数据,1  <= N<=   100000,1 <=  Ai <=  N。

题目大意是给你一串数,从1开始,你可以从i跳至a[i],也可以a[i]++或a[i]–
最少需要多少次(一次操作:跳,或+1,或-1)才能跳到n

比赛一开始看题我有点懵逼,smg?
那么就用DP,f[i]代表跳到i处的最优值
f[i]=min(f[i],f[j]+abs(a[j]-i)+1)
输出答案f[n]

比赛完出来,妥妥30分

听讲后才发现是大水题,直接宽搜O(n)过了
跳过的点不用再跳,搞一搞就没了
真TM很想吐槽这题

代码:

var
        team:array[0..1000000,0..2]of longint;
        bz:array[0..1000000]of boolean;
        a:array[0..1000000]of longint;
        n,i,j,head,tail,x,y:longint;
function min(x,y:longint):longint;
begin
        if xthen exit(x);
        exit(y);
end;
begin
        //assign(input,'walk.in');reset(input);
        //assign(output,'walk.out');rewrite(output);
        readln(n);
        for i:=1 to n do read(a[i]);
        team[1,1]:=a[1];
        team[1,2]:=1;
        fillchar(bz,sizeof(bz),true);
        bz[0]:=false;
        bz[1]:=false;
        bz[n+1]:=false;
        head:=0;
        tail:=1;
        while headdo
        begin
                inc(head);
                x:=team[head,1];
                if x=n then
                begin
                        writeln(team[head,2]);
                        halt;
                end;
                if bz[a[x]]then
                begin
                        inc(tail);
                        team[tail,1]:=a[x];
                        team[tail,2]:=team[head,2]+1;
                        bz[a[x]]:=false;
                end;
                if bz[x+1]then
                begin
                        inc(tail);
                        team[tail,1]:=x+1;
                        team[tail,2]:=team[head,2]+1;
                        bz[x+1]:=false;
                end;
                if bz[x-1]then
                begin
                        inc(tail);
                        team[tail,1]:=x-1;
                        team[tail,2]:=team[head,2]+1;
                        bz[x-1]:=false;
                end;
        end;
end.

你可能感兴趣的:(模拟赛)