标签:描述 pac one namespace isp 一个 表示 com logs
开启了升降梯的动力之后,探险队员们进入了升降梯运行的那条竖直的隧道,映入眼帘的是一条直通塔顶的轨道、一辆停在轨道底部的电梯、和电梯内一杆控制电梯升降的巨大手柄。
Nescafe 之塔一共有N 层,升降梯在每层都有一个停靠点。手柄有M个控制槽,第i 个控制槽旁边标着一个数Ci,满足C1<C2<C3<??<CM。如果Ci>0,表示手柄扳动到该槽时,电梯将上升Ci 层;如果Ci<0,表示手柄扳动到该槽时,电梯将下降-Ci 层;并且一定存在一个Ci=0,手柄最初就位于此槽中。注意升降梯只能在1到N 层间移动,因此扳动到使升降梯移动到1 层以下、N 层以上的控制槽是不允许的。
电梯每移动一层,需要花费2 秒钟时间,而手柄从一个控制槽扳到相邻的槽,需要花费1 秒钟时间。探险队员现在在1 层,并且想尽快到达N 层,他们想知道从1 层到N 层至少需要多长时间?
输入格式:
第一行两个正整数 N、M。
第二行M 个整数C1、C2??CM。
输出格式:
输出一个整数表示答案,即至少需要多长时间。若不可能到达输出-1。
6 3 -1 0 2
19
对于30% 的数据,满足1≤N≤ 10; 2≤M≤ 5。
对于100% 的数据,满足1≤N≤1000; 2 ≤ M ≤20;-N < C1 <C2 < …… < CM < N。
样例解释
手柄从第二个槽扳到第三个槽(0 扳到2),用时1 秒,电梯上升到3层,用时4 秒。
手柄在第三个槽不动,电梯再上升到5 层,用时4 秒。
手柄扳动到第一个槽(2 扳到-1),用时2 秒,电梯下降到4 层,用时2 秒。
手柄扳动到第三个槽(-1 扳倒2),用时2 秒,电梯上升到6 层,用时4 秒。
总用时为(1+4)+4+(2+2)+(2+4)=19 秒。
这套题考的是图论专题,欧教说这题是spfa。。。。对于这个我有点懵????
SPFA????????
好吧说实话我并没有看出来,也不知道怎么去建边建点。。我是用dp做的这道题
事后同学也说是spfa。。。我。。。。
好吧我是萌新我不知道大佬们的spfa是咋做的
我来讲我的dp做法吧
dp[i][j]表示在第i层的时候在第j槽。。。。
这个应该不能理解,这个定义同时也可以理解成,在i层的时候,上一次停留是在i-a[j]层
然后我们在转移状态的时候只需要枚举一下在第i-a[j]层的时候的手柄停留在哪个槽,比如枚举是在第k个槽
那么在从i-a[j]层到i层需要花费的时间是abs(k-j)+abs(a[j])*2
ok这样就可以得出状态转移方程式了
dp[i][j]=min( dp[i][j] , { dp[ i -a[j] ][ k ] + abs( k - j ) + abs ( a[j] ) * 2 }(1<=k<=m) )
做到这里,大体就完成了。。。但是不知道有没有注意到一个细节,就是i到底应该从n到1循环还是从1到n循环。。。。
好吧这个不是大问题,关键在于这个上升楼层有负数,即可以下降。。。。意思是无论我们从n到1还是1到n都不能转移完所有状态
所有这里可以check一下,如果在dp后数组的值有变化就再来一次,直到数组的值不会变化了。。。这里可以用while实现
1 #include<cstdio> 2 #include<queue> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<cmath> 7 #include<cstdlib> 8 #define maxn 1005 9 #define maxm 22 10 using namespace std; 11 12 int n,m,a[maxm],s,ans=0x3f3f3f,f[maxn][maxm]; 13 int cando=1,val[maxn][maxm]; 14 15 void change() 16 { 17 for(int i=1;i<=n;i++) 18 for(int j=1;j<=m;j++) 19 val[i][j]=f[i][j]; 20 } 21 22 void check() 23 { 24 for(int i=1;i<=n;i++) 25 for(int j=1;j<=m;j++) 26 { 27 if(val[i][j]!=f[i][j]){ 28 cando=1;return;//有变动 29 } 30 } 31 cando=0;//无变动 32 } 33 34 int main() 35 { 36 memset(f,0x3f3f3f,sizeof(f)); 37 scanf("%d%d",&n,&m); 38 for(int i=1;i<=m;i++){ 39 scanf("%d",&a[i]);if(a[i]==0)s=i; 40 } 41 f[1][s]=0; 42 for(int i=1;i<=m;i++){if(i!=s)f[1][i]=abs(s-i);} 43 44 while(cando==1){ 45 change(); 46 for(int i=n;i>=1;i--) 47 { 48 for(int j=1;j<=m;j++) 49 { 50 if(j!=s){ 51 int ncnt=i-a[j]; 52 if(ncnt<1||ncnt>n)continue; 53 for(int k=1;k<=m;k++){ 54 if(k!=s){ 55 int ntim=abs(k-j)+abs(a[j])*2; 56 f[i][j]=min(f[i][j],ntim+f[ncnt][k]); 57 } 58 } 59 } 60 if(i==n)ans=min(ans,f[n][j]); 61 } 62 } 63 check(); 64 } 65 66 if(ans==0x3f3f3f)printf("-1"); 67 else printf("%d",ans); 68 }
标签:描述 pac one namespace isp 一个 表示 com logs
原文地址:http://www.cnblogs.com/Danzel-Aria233/p/7619745.html