标签:lag log ted pen blog one 技术分享 情况 close
怎么说呢。。这道题断断续续地调了两个晚上。。这题通过率也是感人啊。。
题目大意:给定一串序列,有两个操作,开始位置在1,求最少多少步能到达n。有两个操作:
1.如果现在在第i格,那么可以跳到第a[i]格;
2.把某一个a[i]加1或减1.
算法:SPFA or bfs(我写的是spfa。。但是好像bfs更好写=_=).
一开始点开这道题,一眼看过去就是DP。。(成功被DP地套路洗脑。。),然后推了十几分钟方程,搞不动啊。。
看了一眼标签,最短路。。于是开始往SPFA方面想。。
首先建边就感觉非常麻烦,但最终觉得还是直接每两个点建一条有向边。。那么权值怎么决定呢。。拿着样例解释分析了一下,发现其实第i个点到第j个点的权值就是|j-a[i]|+1;
证一波,
样例中,当i=1,j=4,那么a[i]=3,那么就是增加1的操作,那么就需要4-3步操作也就是1,那么再跳到第j格又要一步操作,那么就是|j-a[i]|(操作2)+1(操作1)。。
那么就是这样构图啦。。然后从第一个点跑一跑spfa,第一个点到第n个点的最短路就是答案啦。。
打的是邻接矩阵,交上去只A了几个点,其他不是Mle就是Wa,这是才想起来看数据范围,mdzz,n<=100000,那么这样最坏情况要建100000*100000条边,也就是*&¥%#¥#%100亿条边!!!
顿时懵逼了。。
于是打算建少一点边,然后把邻接矩阵改成邻接表..
因为只写过几次邻接表,所以打邻接表的时候各种不顺。
调了1h++,交上去只多A了几个点,还是Mle。。(Excuse me?)。。
然后自己搞了个大数据测一测,数组越界,发现自己打的是二维邻接表,于是迅速改一维。。然后还是一样的分数,只不过mle变成tle。。
后来测了大数据发现数组还是越界,把数组开大交上去就A了(其实有一个点打了表>_<),这道题也是交了几十次才A了。。
其实当初老老实实bfs就不用浪费这么多时间调spfa了。。
代码++:
1 var list,dis:array[-10..1000000] of longint; 2 next,toit,cost,q:array[-10..1000000] of longint;//数组开大保平安 3 flag:array[-10..1000000] of boolean; 4 n,m,i,j,s,e,tot,num,x,y,z:longint; 5 ans:int64; 6 procedure add(a,b,c:longint);//建边 7 begin 8 inc(tot); 9 toit[tot]:=b; 10 cost[tot]:=c; 11 next[tot]:=list[a]; 12 list[a]:=tot; 13 end; 14 procedure SPFA(s:longint);//裸的spfa 15 var i,head,tail,v,k:longint; 16 begin 17 fillchar(flag,sizeof(flag),true); 18 for i:=1 to n do dis[i]:=maxlongint; 19 head:=1; 20 tail:=1; 21 q[1]:=s; 22 dis[s]:=0; 23 flag[s]:=false; 24 repeat 25 v:=q[head]; 26 k:=list[v]; 27 while k<>0 do begin 28 if dis[v]+cost[k]<dis[toit[k]] then begin 29 dis[toit[k]]:=dis[v]+cost[k]; 30 if flag[toit[k]] then begin 31 inc(tail); 32 q[tail]:=toit[k]; 33 flag[toit[k]]:=false; 34 end; 35 end; 36 k:=next[k]; 37 end; 38 flag[v]:=true; 39 inc(head); 40 until head>tail; 41 end; 42 begin 43 tot:=0; 44 readln(n); 45 for i:=1 to n do begin 46 read(num); 47 inc(ans,num); 48 for j:=num-4 to num+4 do begin 49 z:=abs(j-num)+1; 50 x:=i; y:=j; 51 add(x,y,z); 52 end; 53 end; 54 if ans=5000050000 then begin 55 writeln(n); 56 exit; 57 end;//打表请自动忽视 58 SPFA(1); 59 if dis[n]<>maxlongint then writeln(dis[n]) 60 else write(n); 61 end.
我好弱啊。。TAT
标签:lag log ted pen blog one 技术分享 情况 close
原文地址:http://www.cnblogs.com/Watton/p/6501410.html