P1772 [ZJOI2006] 物流运输

P1772 [ZJOI2006] 物流运输

Description

一批货物从码头 A 运到码头 B。需要 n n n 天才能运完,要转停好几个码头。
若某个码头会关闭,必须修改运输路线并带来损耗。要求订一个 n n n 天的运输计划,最小化总成本。

n n n 表示货物运输所需天数, m m m 表示码头数, k k k 表示每次修改路线成本, e e e 表示航线条数。

e e e双向航线描述:航线连接两个码头编号、航线费用。其中码头 A 编号为 1 1 1,码头 B 编号为 m m m

d d d 个不可用码头时间: p , a , b p,a,b p,a,b。表示编号为 p p p 的码头在 [ a , b ] [a,b] [a,b] 天之内无法装卸货物。同一个码头有可能在多个时间段内不可用。保证任何时间存在从码头 A 到码头 B 的运输路线。

总成本为 n n n 天运输路线长度之和 + k × + k \times +k× 改变路线的次数。
求最小总成本。
对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 100 1 \le n \le 100 1n100 1 ≤ m ≤ 20 1\le m \le 20 1m20, 1 ≤ k ≤ 500 1 \le k \le 500 1k500, 1 ≤ e ≤ 200 1 \le e \le 200 1e200

Solution

Pre:
这题初见看到 m ≤ 20 m\le 20 m20 ,想了想感觉是状压路径(除掉共同终点 m m m 2 m − 1 2^{m-1} 2m1 条),然后按天数转移,最后写完 b f s + bfs+ bfs+状压线性DP 偷了 10 p t s 10pts 10pts, 好像是 b f s bfs bfs 写炸导致队列 M L E MLE MLE。最后死都没调出来不想调
倒是你谷还是有神犇写了 d f s + dfs+ dfs+状压线性DP 暴力AC,我也算这个做法颅内AC了(第一次过是Copy这位的标程,把自己的代码放在地下注释掉后提交的qwq…)

Now:
题后参考了题解:
n 2 n^2 n2 处理 n l o g n + m nlogn+m nlogn+m 的最短路——求出第 i i i j j j 天的最短路 c [ i ] [ j ] c[i][j] c[i][j] i ∼ j i\sim j ij只走同一路线的最小花费)
DP状态: f [ i ] f[i] f[i] 为前 i i i 天最优方案
状态转移: f [ i ] = m i n ( f [ j − 1 ] + c [ j ] [ i ] ∗ ( i − j + 1 ) + k ) , j ∈ [ 1 , i ] f[i]=min(f[j-1]+c[j][i]*(i-j+1)+k), j\in[1,i] f[i]=min(f[j1]+c[j][i](ij+1)+k),j[1,i]
特别地:由于第 0 0 0 天到 第 1 1 1 天“切换路线”无意义,所以使 f [ 0 ] = − k f[0]=-k f[0]=k(抵消无效转移成本 k k k )。

题外话:本题按天数转移的方程类似于 UVA11400 照明系统设计 Lighting System Design ,本蒟蒻当天才写完对着紫书贺思路qwq

Code
	d=read();
	for(ll i = 1; i <= d ; i++){
		ll p=read(), l=read(), r=read();
		for(ll j = l ; j <= r ; j++) un[j][p]=1;//第j天第p码头不可行
	}
	
	memset(f, 0x3f, sizeof(f));
	f[0]=-k;//特别的
	for(ll i = 1; i <= n ; i++){
		memset(non, 0, sizeof(non));//区间时间内的不可达码头
		for(ll j = i; j > 0 ; j--){//从第i天向第j天反着推
			for(ll p = 1; p <= m ; p++)//每天更新当天不可用码头即可(小优化)
			if(un[j][p]) non[p]=1;
			
		 	ll nw=Dijkstra();
		 	if(nw>=1e16) break;
		 	f[i]=min(f[i], f[j-1]+(i-j+1)*nw+k);
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值