(JZ1274)2019.01.26【NOIP提高组】模拟B组 1.游历的路线

游历的路线(lines.pas/cpp)

Description

我们的郭嘉大大经过一段时间发现了袁绍这个人干大事而惜身,见小利而忘义,又逢曹操在招兵买马,决定逃离袁绍去投曹操,而我们的曹操在第M天招募良材,我们的郭嘉大大既不能早去,也不能晚去,于是乎,他就趁着这一段时间到其他的城市游历一番,而每两个城市之间只能坐马车来往,由于我们的郭嘉大大很贪钱,他想用最少的费用,所以需要我们帮他求出这一个最小的费用。

Input

第一行包含两个数n,m, 表示有n个城市,和m天后曹操招纳良材。城市一就是郭嘉所在的城市,城市n就是曹操处。接下来n * (n – 1)行描述马车乘坐表。   第2到第n行就是描述的城市1到2… n的马车乘坐表.   第n + 1到第2n-1行描述的城市2到城市1,3…n的马车乘坐表… … 对每一行,首先有一个数T,表示城市I到城市J的马车以T为周期,接下来有T个数,表示每天的马车的价格,如果价格为0则表示没有马车可坐。(n <= 100, m <= 200, T <= 20, Price <= 50000)

Output

如果存在这样的路线使郭嘉第m天到达曹操处,则输出最少的费用,否则输出0!

Sample Input
3 5
2 130 150
3 75 0 80
2 110 100
4 60 70 60 50
3 0 135 140
2 70 80

Sample Output
355

题解:

   本题是floyd
   本题一定要先看懂题意,不要问我为什么,写了半天发现输入搞错了,又得重写ε=(´ο`*)))
   题目的背景条件是郭嘉一直走,最后到m点,求最小代价。本题的输入是隐晦地告诉了我们,每个城市到另外所有城市的价格。为什么是隐晦呢,因为他只是把周期告诉了我们,把周期代入进数组就是我们要做的事啊!(也就是处理出各个城市间的代价数组a)
   那么条件就明朗了,我们有两个状态:天数和城市。再看看数据范围:n <= 100, m <= 200,用floyd不会炸(如果数据够大的话,就得用spfa了)
   我们设f[i][j]为在i天到城市j的最小代价。1个for天数,2个for城市,易得状态转移方程:f[i,j]:=min(f[i,j],f[k,j-1]+a[k,i,j])

var
 a:array[0..210,0..210,0..210] of longint;
 f:array[0..210,0..210] of longint;
 n,m,i,j,k,x,t,l:longint;

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

begin
assign(input,'lines.in'); reset(input);
assign(output,'lines.out'); rewrite(output);

  read(n,m);
  for i:=1 to n do
   for j:=1 to n do
    begin
      if i=j then continue;
      read(t);
      for k:=1 to t do
       begin
        read(x);
        if x=0 then x:=maxlongint div 3;//当代价为0时,就是没有路的意思
        a[i,j,k]:=x;
       end;
      for k:=t+1 to m do
       begin
        l:=k mod t;
        if l=0 then l:=t;
        a[i,j,k]:=a[i,j,l];
       end;
    end;
  fillchar(f,sizeof(f),$7F div 3);
  f[1,0]:=0;
  for j:=1 to m do
   for i:=1 to n do
    for k:=1 to n do
     if i<>k then f[i,j]:=min(f[i,j],f[k,j-1]+a[k,i,j]);
  if f[n,m]=maxlongint div 3 then write(0)
                             else write(f[n,m]);

close(input);close(output);
end.
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值