【BZOJ1820】[JSOI2010]快递服务(动态规划)

【BZOJ1820】[JSOI2010]快递服务(动态规划)

题面

BZOJ
洛谷

题解

考虑无脑四维\(dp\)\(f[i][a][b][c]\),表示当前处理到第\(i\)个任务,三辆车的位置分别在\(a,b,c\)的最小值。
发现\(a,b,c\)中一定有一个等于第\(i\)个任务的位置,显然可以再咕掉一维。这样子状态就只有三维,也就是\(O(nm^2)\),然而空间小,再滚一维就好了。
时间复杂度\(O(nm^2)\)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define ll long long
#define MAX 205
inline int read()
{
	int x=0;bool t=false;char ch=getchar();
	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
	if(ch=='-')t=true,ch=getchar();
	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
	return t?-x:x;
}
int d[MAX][MAX];
int f[2][MAX][MAX];
int n,x,nw,pw,a[1010],m,ans;
void cmin(int &x,int y){x=min(x,y);}
int main()
{
	n=read();
	for(int i=1;i<=n;++i)
		for(int j=1;j<=n;++j)
			d[i][j]=read();
	memset(f,63,sizeof(f));
	f[0][2][3]=0;a[0]=1;nw=0;pw=1;
	while(scanf("%d",&x)!=EOF)
	{
		swap(nw,pw);a[++m]=x;
		memset(f[nw],63,sizeof(f[nw]));
		for(int i=1;i<=n;++i)
			for(int j=1;j<=n;++j)
			{
				cmin(f[nw][i][j],f[pw][i][j]+d[a[m-1]][x]);
				if(a[m-1]<j)cmin(f[nw][a[m-1]][j],f[pw][i][j]+d[i][x]);
				else cmin(f[nw][j][a[m-1]],f[pw][i][j]+d[i][x]);
				if(a[m-1]<i)cmin(f[nw][a[m-1]][i],f[pw][i][j]+d[j][x]);
				else cmin(f[nw][i][a[m-1]],f[pw][i][j]+d[j][x]);
			}
		ans=1e9;
		for(int i=1;i<=n;++i)
			for(int j=1;j<=n;++j)
				ans=min(ans,f[nw][i][j]);
		cerr<<ans<<endl;
	}
	printf("%d\n",ans);
	return 0;
}
posted @ 2018-10-17 16:51  小蒟蒻yyb  阅读(285)  评论(0编辑  收藏  举报