BZOJ 1820: [JSOI2010]Express Service 快递服务 DP

题意

题解

这里用nn表示地点数,mm表示要送的快递数。

很容易想出O(n3m)O(n^3m)的算法,就是把33个点状态存下来。

可是过不了。

但是可以省略一维,因为一定有一个车在上一个地点。

所以就简单了。

CODE

不一定要保证状态f(i,j)f(i,j)i<ji<j

#pragma GCC optimize (2)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int MAXN = 205;
LL f[2][MAXN][MAXN];
int d[MAXN][MAXN], n, m;
int main () {
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= n; ++j)
			scanf("%d", &d[i][j]);
	int cur = 0, lst = 1, now;
	memset(f[cur], 0x3f, sizeof f[cur]);
	f[cur][2][3] = 0;
	while(scanf("%d", &now) != EOF) {
		cur ^= 1, memset(f[cur], 0x3f, sizeof f[cur]);
		for(int i = 1; i <= n; ++i)
			for(int j = 1; j <= n; ++j) {
				f[cur][i][j] = min(f[cur][i][j], f[cur^1][i][j] + d[lst][now]);
				f[cur][lst][j] = min(f[cur][lst][j], f[cur^1][i][j] + d[i][now]);
				f[cur][i][lst] = min(f[cur][i][lst], f[cur^1][i][j] + d[j][now]);
			}
		lst = now;
	}
	LL ans = f[0][0][0];
	for(int i = 1; i <= n; ++i)
		for(int j = 1; j <= n; ++j)
			ans = min(ans, f[cur][i][j]);
	printf("%lld
", ans);
}
原文地址:https://www.cnblogs.com/Orz-IE/p/12039217.html