P4046 [JSOI2010]快递服务

题目链接 双倍经验

大致题意

(m)个位置,从位置(p)移动到位置(q)需要花费(c(p,q))的价钱,但并不保证(c(p,q)≠c(q,p))

现在有三个员工,初始位置在(1,2,3)和有(n)个请求,任何时刻只有一名员工可以移动,且不允许同一位置上有 (2) 个以上员工。第 (i) 个请求发生在位置 (p_i),公司必须按照顺序,派一名员工到位置 (p_i)去完成请求

求公司的最小花费。

分析

(f(i,x,y,z))表示解决完前(i)个请求时,三个员工分别在(x,y,z)处时的最小花费,转移:

(f(i+1,p_{i+1},y,z) = min{f(i,x,y,z)+c(x,p_{i+1})}qquad (p_{i+1}≠y≠z))

(f(i+1,x,p_{i+1},z) = min{f(i,x,y,z)+c(y,p_{i+1})}qquad (x≠p_{i+1}≠z))

(f(i+1,x,y,p_{i+1}) = min{f(i,x,y,z)+c(z,p_{i+1})}qquad (x≠y≠p_{i+1}))

时空复杂度(O(nm^3)),无论是在时间上还是空间上都接受不了

考虑优化:

可以发现,在完成第(i)个任务时,一定有一个人站在(p_i)的位置上,也就是说,这个人的信息是"多余"的,只需要记录另外两个人的位置

(f(i,x,y))表示解决前(i)个请求时,三个员工分别在(x,y,p_i)时的最小花费,转移:

(f(i+1,p_i,y) = min{f(i,x,y)+c(x,p_{i+1})}qquad (p_i≠y≠p_{i+1}))

(f(i+1,x,y) = min{f(i,x,y)+c(p_i,p_{i+1})}qquad (x≠y≠p_{i+1}))

(f(i+1,x,p_i) = min{f(i,x,y)+c(y,p_{i+1})}qquad (x≠p_i≠p_{i+1}))

时间复杂度(O(nm^2)),再用滚动数组优化一下空间即可

(code)

/*
xcxc82
*/
#include<bits/stdc++.h>
using namespace std;
#define inf 1e9+10
const int MAXN = 210;
int T,L,n;
inline int read(){
	int X=0; bool flag=1; char ch=getchar();
	while(ch<'0'||ch>'9') {if(ch=='-') flag=0; ch=getchar();}
	while(ch>='0'&&ch<='9') {X=(X<<1)+(X<<3)+ch-'0'; ch=getchar();}
	if(flag) return X;return ~(X-1);
}
int f[2][MAXN][MAXN];
int val[MAXN][MAXN],a[MAXN*5];
int main(){
		memset(f,0x3f,sizeof(f));
		L = read();
		for(int i=1;i<=L;i++){
			for(int j=1;j<=L;j++){
				val[i][j] = read();
			}
		}
	    a[0] = 3;
		f[0][1][2] = 0;
		int now;
		while(cin>>now) a[++n] = now;
		for(int i=0;i<=n-1;i++){
			memset(f[i+1&1],0x3f,sizeof(f[i+1&1]));
			for(int x=1;x<=L;x++){
				for(int y=1;y<=L;y++){
					if(x==y||x==a[i]||y==a[i]) continue;
					f[i+1&1][a[i]][y] = min(f[i+1&1][a[i]][y],f[i&1][x][y]+val[x][a[i+1]]);
					f[i+1&1][x][y] = min(f[i+1&1][x][y],f[i&1][x][y]+val[a[i]][a[i+1]]);
					f[i+1&1][x][a[i]] = min(f[i+1&1][x][a[i]],f[i&1][x][y]+val[y][a[i+1]]);
				}
			}
		}
		int ans = 0x3f3f3f3f;
		
		for(int i=1;i<=L;i++) 
		 for(int j=1;j<=L;j++) 
		  ans = min(ans,f[n&1][i][j]);
		  
		printf("%d",ans);
   return 0;
}






原文地址:https://www.cnblogs.com/xcxc82/p/14300486.html