关于空间
查看原帖
关于空间
396064
GaryGe楼主2023/9/9 14:41

可能更优的空间复杂度,请问是否正确

/*
f[i][j][k]表示处理到 i 其余两人位置为 j,k
f[i][j][k]=min{f[i-1][j][k]+C(a[i-1],a[i])}
f[i][a[i-1]][k]=min{f[i-1][p][k]+C(p,a[i])}
f[i][j][a[i-1]]=min{f[i-1][j][p]+C(p,a[i])}
O(L^2)
发现只需要记录 f[i][a[i-1]][?]和 f[i][?][a[i-1]]的路径
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF=1e18;
const ll L=205;
const ll N=1e3+5;
ll l,n,c[L][L],a[N],f[2][L][L],pre1[N][L],pre2[N][L];
struct Node{ll x,y,z;};
Node dfs(ll u,ll x,ll y)
{
	if (u==0) return (Node){1,2,3};
	Node res;
	if (x==a[u-1])
	{
		if (pre1[u][y])
		{
			res=dfs(u-1,pre1[u][y],y);
			swap(res.x,res.y);
		}
		else res=dfs(u-1,x,y);
	}
	else if (y==a[u-1])
	{
		if (pre2[u][x])
		{
			res=dfs(u-1,x,pre2[u][x]);
			swap(res.x,res.z);
		}
		else res=dfs(u-1,x,y);
	}
	else res=dfs(u-1,x,y);
	cout << res.x << ' ';
	return res;
}
int main()
{
	cin >> l >> n;
	for (int i=1;i<=l;i++)
		for (int j=1;j<=l;j++)
			cin >> c[i][j];
	for (int i=1;i<=n;i++) cin >> a[i];
	for (int j=1;j<=l;j++)
		for (int k=1;k<=l;k++)
			f[0][j][k]=INF;
	a[0]=1,f[0][2][3]=0;
	for (int i=1;i<=n;i++)
	{
		for (int j=1;j<=l;j++)
			for (int k=1;k<=l;k++)
			{
				if (j==k||j==a[i]||k==a[i]) f[i&1][j][k]=INF;
				else f[i&1][j][k]=f[!(i&1)][j][k]+c[a[i-1]][a[i]];
			}
		if (a[i]==a[i-1]) continue;
		// f[i][a[i-1]][k]=min{f[i-1][p][k]+C(p,a[i])}
		for (int k=1;k<=l;k++)
		{
			if (k==a[i]) continue;
			for (int p=1;p<=l;p++)
			{
				if (p==k||p==a[i-1]) continue;
				if (f[i&1][a[i-1]][k]<=f[!(i&1)][p][k]+c[p][a[i]]) continue;
				f[i&1][a[i-1]][k]=f[!(i&1)][p][k]+c[p][a[i]],pre1[i][k]=p;
			}
		}
		// f[i][j][a[i-1]]=min{f[i-1][j][p]+C(p,a[i])}
		for (int j=1;j<=l;j++)
		{
			if (a[i]==j) continue;
			for (int p=1;p<=l;p++)
			{
				if (j==p||p==a[i-1]) continue;
				if (f[i&1][j][a[i-1]]<=f[!(i&1)][j][p]+c[p][a[i]]) continue;
				f[i&1][j][a[i-1]]=f[!(i&1)][j][p]+c[p][a[i]],pre2[i][j]=p;
			}
		}
	}
	ll ans=INF,x,y;
	for (int i=1;i<=l;i++)
		for (int j=1;j<=l;j++)
		{
			if (a[n]==i||a[n]==j||i==j||ans<=f[n&1][i][j]) continue;
			ans=f[n&1][i][j],x=i,y=j;
		}
	cout << ans << endl;
	dfs(n,x,y);
	return 0;
}
2023/9/9 14:41
加载中...