【DP】Mobile Service(jzoj 1327)

Mobile Service

jzoj 1327

题目大意

某公司有三个员工,现在有n个时刻,某一时刻要一个员工到一个位置(别的员工不能动),代价为 c i , j c_{i,j} ,一个位置一个时刻最多有一个人,问最小代价是多少

输入样例

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

输出样例

5

数据范围

3 L 200 3\leqslant L\leqslant 200
1 N 1000 1\leqslant N\leqslant 1000
c i , j 2000 c_{i,j}\leqslant 2000

解题思路

我们设 f i , x , y , z f_{i,x,y,z} 为i时刻三个员工分别位于x、y、z,然后状态转移方程显而易见了,当我们需要优化
我们可以减少一个z,因为i时刻一定有个员工在指定位置
最后我们还要滚动一波

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n, m, ans, a[1050], c[250][250], f[2][202][202];
int main()
{
	scanf("%d %d", &m, &n);
	for (int i = 1; i <= m; ++i)
		for (int j = 1; j <= m; ++j)
			scanf("%d", &c[i][j]);
	memset(f, 127/3, sizeof(f));
	f[0][2][3] = 0;
	a[0] = 1;
	for (int i = 1; i <= n; ++i)
	{
		memset(f[i&1], 127/3, sizeof(f[i&1]));
		scanf("%d", &a[i]);
		for (int x = 1; x <= m; ++x)
			for (int y = 1; y <= m; ++y)
				if (a[i - 1] != x && x != y && a[i - 1] != y)
				{
					if (a[i - 1] == a[i])//防止有重复的
						f[i&1][x][y] = min(f[i&1][x][y], f[(i + 1)&1][x][y]);
					else if (x == a[i])
						f[i&1][a[i - 1]][y] = min(f[i&1][a[i - 1]][y], f[(i + 1)&1][x][y]);
					else if (y == a[i])
						f[i&1][x][a[i - 1]] = min(f[i&1][x][a[i - 1]], f[(i + 1)&1][x][y]);
					else
					{
						f[i&1][x][y] = min(f[i&1][x][y], f[(i + 1)&1][x][y] + c[a[i - 1]][a[i]]); //转移
						f[i&1][a[i - 1]][y] = min(f[i&1][a[i - 1]][y], f[(i + 1)&1][x][y] + c[x][a[i]]);
						f[i&1][x][a[i - 1]] = min(f[i&1][x][a[i - 1]], f[(i + 1)&1][x][y] + c[y][a[i]]); 
					}		
				}
	}
	ans = 2147483646;
	for (int x = 1; x <= m; ++x)
		for (int y = 1; y <= m; ++y)
			if (a[n] != x && x != y && a[n] != y)
				ans = min(ans, f[n&1][x][y]); 
	printf("%d", ans);
	return 0;
} 
发布了334 篇原创文章 · 获赞 57 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/ssllyf/article/details/104335687