10.8 上学 2404

题目

FJ的农场有n个小镇, 奶牛bessi在小镇0,它的学校在小镇n-1. bessi要坐车到学校去上学. N个小镇之间有公交车, bessi就是坐公交车去上学. 小镇之间有m部公交车,我们用(a, b, leave, time, cost) 来描述一部公交车的信息: 表示有一部公交车在时刻leave从小镇a出发, 经过time分钟到达城市b, 车票价格是cost. 由于bessi今天睡过头了,他希望在t分钟以内(包括t分钟)从小镇0到达小镇n-1. 他应该怎样坐公交车才能用最少的车费又能准时上学? 注意: 若bessi在时刻x刚好到达小镇a, 如果公交车的出发时刻也恰好是时刻x, 那么我们规定bessi无法坐到该公交车,也就是说如果想坐这趟公交车则必须在时刻x之前到达小镇a. 当然,有一种情况例外, 小镇0的公交车如果是0时刻出发, bessi在时刻0是可以坐这趟公交车的. 0时刻bessi在小镇0处.

题解

我的想法是二分花费,然后Spfa判断花费是否可行
但是正解是DP,其实正解的DP和Spfa应该是一个意思,只是表达方式不同
DP数组的定义十分的套路:f[i,j]表示i时刻到达j小镇的最小话费
然后仍旧十分套路的考虑正推还是反推,为了方便正解考虑正推,也就是考虑当前情况已经得出答案,要由当前情况推出下一情况
接下来还是十分套路的考虑对情况进行分类,套路地分出留在这个点和从第k条路去往另一个点,于是:
i 0—t
j 1—n-1
k 1—m
a[k]=j leave[k]=i leave[k]+time[k]+1<=t —>f[leave[k]+time[k]+1,b[k]]=f[i,j] 走
f[i+1,j]=min(f[i,j],f[i+1,j]) 留

代码

var
  a,b,l,t,c:array[1..50]of longint;
  f:array[0..10001,0..50]of longint;
  n,m,s,i,j,k:longint;

function min(a,b:longint):longint;
begin
  if a<b then exit(a) else exit(b);
end;

begin
  readln(n,s,m);
  for i:=1 to m do
    readln(a[i],b[i],l[i],t[i],c[i]);
  fillchar(f,sizeof(f),$7f);
  f[0,0]:=0;
  for i:=0 to s do
    for j:=0 to n-1 do
      begin
        if f[i,j]=f[0,50] then continue;
        for k:=1 to m do
          if (a[k]=j)and(i=l[k])and(l[k]+t[k]<=s+1) then
            f[l[k]+t[k]+1,b[k]]:=min(f[l[k]+t[k]+1,b[k]],f[i,j]+c[k]);
        f[i+1,j]:=min(f[i+1,j],f[i,j]);
      end;
  if f[s+1,n-1]=f[0,50] then writeln(-1) else writeln(f[s+1,n-1]);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值