[动态规划]Mobile Service

 

From xjx8599

Mobile Service

 

 

 

 

 

 

 

 

描述 Description

 

 

一个公司有三个移动服务员。如果某个地方有一个请求,某个员工必须赶到那个地方去(那个地方没有其他员工),某一时刻只有一个员工能移动。被请求后,他才能移动,不允许在同样的位置出现两个员工。从p到q移动一个员工,需要花费c(p,q)。这个函数没有必要对称,但是c(p,p)=0。公司必须满足所有的请求。目标是最小化公司花费。

 

 

 

 

 

 

 

输入格式 Input Format

 

 

第一行有两个整数L,N(3<=L<=200, 1<=N<=1000)。L是位置数;N是请求数。每个位置从1到L编号。下L行每行包含L个非负整数。第i+1行的第j个数表示c(i,j) ,并且它小于2000。最后一行包含N个数,是请求列表。一开始三个服务员分别在位置1,2,3。

 

 

 

 

 

 

 

输出格式 Output Format

 

 

一个数M,表示最小服务花费。

 

 

 

 

 

 

 

样例输入 Sample Input [复制数据]

 

 

 

 

 

 

 

 

 

样例输出 Sample Output [复制数据]

 

 

 

 

 

 

 

 

 

时间限制 Time Limitation

 

 

各个测试点1s

 

 

 

 

 

 

 

Flag

  Accepted

题号

  P1061

类型(?)

  动态规划

通过

  701人

提交

  1676次

通过率

  42%

难度

  3

 

 

 

 

 

 

 

 

提交

讨论

题解

记录

数据

 

 

 

 

 

 

 

看到此题可以快速想到一个暴力dp。

f[i,x,y,z]表示前i次服务,第1,2,3个人的位置为x,y,z。

p[i]表示第i次服务的地点。c[i,j]表示从i到j的花费

对于第i个请求,显然只有三种决策。让x去,让y去,让z

f[i,p[i],y,z]=f[i-1,x,y,z]+c[x,p[i]] //x去

其余类推。

 

显然这个会超空间超时。

所以我们要减少状态。

显然在第i时刻必然有一个人的位置在p[i-1],于是只需要表示两个人的位置。

f[i,x,y]表示第i时刻 第1,2,3个人的位置为x,y,p[i-1]

则f[i-1,x,y]+c[p[i-1],p[i]]=f[i,x,y]   p[i-1]换到p[i]

    f[i-1,x,y]+c[y,p[i]]=f[i,x,p[i-1]]  y换到p[i]

    f[i-1,x,y]+c[x,p[i]]=f[i,y,p[i-1]]  x换到p[i]

 

这个方程的解释如下

i-1 个请求后 三个位置为 x,y,p[i-1]   用f[i-1,x,y]表示

对于第i个请求,有三种决策。

x去,那么三个位置变为y,p[i-1],p[i+1] 用f[i,y,p[i-1]]表示

 

其余类推

 

var i,j,n,m,x1,x2,x3,ans:longint;
    c:array[1..200,1..200]of longint;
    p:array[1..1000]of longint;
    f:array[0..1,1..200,1..200]of longint;

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

begin
    readln(n,m);
    for i:=1 to n do
    begin
    for j:=1 to n do
    read(c[i,j]);
    readln;
    end;
    for i:=1 to m do
    read(p[i]);

    fillchar(f,sizeof(f),$7f);
    f[1,1,2]:=c[3,p[1]];f[1,1,3]:=c[2,p[1]];f[1,2,3]:=c[1,p[1]];
    for i:=2 to m do
    begin
    for x1:=1 to n do
    for x2:=1 to n do
    begin
        f[i mod 2,x1,x2]:=min(f[i mod 2,x1,x2],f[(i-1)mod 2,x1,x2]+c[p[i-1],p[i]]);
        f[i mod 2,x1,p[i-1]]:=min(f[i mod 2,x1,p[i-1]],f[(i-1)mod 2,x1,x2]+c[x2,p[i]]);
        f[i mod 2,x2,p[i-1]]:=min( f[i mod 2,x2,p[i-1]],f[(i-1)mod 2,x1,x2]+c[x1,p[i]]);
    end;
     fillchar(f[(i-1)mod 2],sizeof(f[(i-1)mod 2]),$7f);
    end;
    ans:=maxlongint;
    if m mod 2 =1 then m:=1 else m:=0;
    for i:=1 to n do
    for j:=1 to n do
    if ans>f[m,i,j] then ans:=f[m,i,j];
    writeln(ans);
    readln;readln;
end.


 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值