mobile service:滾動數組的使用

……並不是什麼非常難的題目。

1.f[i][x][y][z]表示在第i輪,三個人分別在x,y,z的最小代價。

2.然而我們經過思考發現這樣設計狀態不是很好。在第i輪,一定有一個售貨員在s[i]的位置,而且我們並不需要知道這三個人分別在哪個位置(就是ABC只要不在同一位置,所有狀態都是一樣的)。所以,我們可以縮減一維,f[i][x][y]表示第i輪,有2個人分別在x,y,另外一個人在s[i]。而狀態也很好轉移。。。就是枚舉一下每一輪分別是哪個人跑到s[i]去。

3.然而我們發現空間不夠用了emmm,所以考慮一下滾動數組。

然後我很悲傷的調了2個小時還不對。。。

血的教訓:滾動數組一定一定要在使用之前清0!!!

#include <bits/stdc++.h>

using namespace std;
const int maxn=1005;
int l,n,c[205][205],s[maxn];
int f[3][205][205];
int main()
{
	scanf("%d%d",&l,&n);
	for(int i=1;i<=l;i++)
	{
		for(int j=1;j<=l;j++)
		{
			scanf("%d",&c[i][j]);	
		}
	}
	for(int i=1;i<=n;i++) scanf("%d",&s[i]);
	memset(f,0x3f,sizeof(f));
	f[1][2][3]=f[1][3][2]=c[1][s[1]];
	f[1][1][3]=f[1][3][1]=c[2][s[1]];
	f[1][1][2]=f[1][2][1]=c[3][s[1]];
	int now=0;
	for(int i=1;i<n;i++)
	{
		now^=1;
	//	cout<<now<<endl;
		memset(f[now^1],0x3f,sizeof(f[now^1]));//這一行超級重要啊 
		for(int x=1;x<=l;x++)
		{
			for(int y=1;y<=l;y++)
			{
			//	if(x==s[i+1]||y==s[i+1]) continue;
			if(x!=s[i+1]&&y!=s[i+1]&&x!=y) f[now^1][x][y]=min(f[now^1][x][y],f[now][x][y]+c[s[i]][s[i+1]]);
			if(s[i]!=s[i+1]&&y!=s[i+1]&&s[i]!=y) f[now^1][s[i]][y]=min(f[now^1][s[i]][y],f[now][x][y]+c[x][s[i+1]]);
			if(x!=s[i+1]&&s[i]!=s[i+1]&&x!=s[i]) f[now^1][x][s[i]]=min(f[now^1][x][s[i]],f[now][x][y]+c[y][s[i+1]]);
	//		cout<<f[now][x][y]<<" ";
			}
		}
	}
	int minv=0x3f3f3f3f;
	for(int x=1;x<=l;x++)
	{
		if(x==s[n]) continue;
		for(int y=1;y<=l;y++)
		{
			if(y==s[n]) continue;
			minv=min(minv,f[now^1][x][y]);
		}
	}
	printf("%d",minv); 
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章