多状态动态规划的压缩

Tvyj1061
Mobile Service

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

第一行有两个整数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。

Sample In

5 9
0 1 1 1 1
1 0 2 3 2
1 1 0 4 1
2 1 5 0 1
4 2 3 4 0
4 2 4 1 5 4 3 2 1

Sample Out

5


这题目有三个状态x1,x2,x3分别是三个人的位置

易得当前把X1赶去p[j]的转移

f[i,p[i],x2,x3]:=f[i,x1,x2,x3]+map[x1,p[i]]

同理

f[i,x1,p[i],x3]:=f[i,x1,x2,x3]+map[x2,p[i]]

f[i,x1,x2,p[i]]:=f[i,x1,x2,x3]+map[x3,p[i]]


但是这里有一个冗余的状态,就是{上一次的位置一定是这一次某个人的位置}


所以简化方程得

f[i,x2,p[i-1]]:=f[i-1,x1,x2]+map[x1,p[i]];
f[i,x1,p[i-1]]:=f[i-1,x1,x2]+map[x2,p[i]];
f[i,x1,x2]:=f[i-1,x1,x2]+map[p[i-1],p[i]];

当三个人的位置是x1,x2,p[i-1]时

让x1去p[i],,这时位置变成p[i],x2,p[i-1]

我们只记录x2和p[i-1]

所以f[i,x2,p[i-1]]:=f[i-1,x1,x2]+map[x1,p[i]];

如此类推就把一个人的位置给压缩掉了(还可以滚动数组优化)


矿工配餐

http://www.tyvj.cn/Problem_Show.asp?id=1180

现有两个煤矿,每个煤矿都雇用一组矿工。采煤工作很辛苦,所以矿工们需要良好饮食。每当一辆食品车到达煤矿时,矿工们便会产出一定数量的煤。有三种类型的食品车:肉车,鱼车和面包车。
矿工们喜欢变化的食谱。如果提供的食品能够不断变化,他们的产煤量将会增加。每当一个新的食品车到达煤矿时,矿工们就会比较这种新的食品和前两次(或者少于两次,如果前面运送食品的次数不足两次)的食品,并且:
如果这几次食品车都是同一类型的食品,则矿工们产出一个单位的煤。
如果这几次食品车中有两种不同类型的食品,则矿工们产出两个单位的煤。
如果这几次食品车中有三种不同类型的食品,则矿工们产出三个单位的煤。
预先已知食品车的类型及其被配送的顺序。通过确定哪车食品送到哪个煤矿可以影响产煤量。食品车不能被拆分,每个食品车必须被全部送到一个或另一个煤矿。两个煤矿也并不要求接收相同数量的食品车(事实上,也允许将所有食品车都送到一个煤矿)。
任务
给出食品车的类型及其被配送的顺序,要求你写一个程序,确定哪个食品车应被送到煤矿1,哪个食品车应被送到煤矿2,以使得两个煤矿的产煤量的总和最大。

输入的第一行包含一个整数N (1 ≤ N ≤ 100 000),  表示食品车的数目。求最大采矿量

样例输入1
6
MBMFFB

样例输出1
12

样例输入2
16

MMBMBBBBMMMMMBMB

样例输出2
29

食物的种类只有三种[0..3,0..3,0..3,0..3]满足空间时间大小

所以记录状态f[i,a1,a2,b1,b2]代表前两次两矿的食品种类

同理有一个状态肯定是上一次食品车的种类 所以压缩一个变量得

f[i,s[i],pa1,pb1,pb2]=max{f[i-1,pa1,pa2,pb1,pb2]+w(s[i],pa1,pa2)}
f[i,pa1,pa2,s[i],pb1]=max{f[i-1,pa1,pa2,pb1,pb2]+w(s[i],pb1,pb2)}
    (1<=i<=n ,0<=pa1<=3 ,0<=pa2<=3 ,0<=pb1<=3 ,0<=pb2<=3)

最后就是W(a,b,c)的函数要小心

同理可以做到滚动数组


总的来说 就是要注意有没有冗余的状态 有的话 一定要简化再简化

12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值