现在的位置: 首页 > 综合 > 正文

poj 3311

2013年03月23日 ⁄ 综合 ⁄ 共 1079字 ⁄ 字号 评论关闭

题意:一个送披萨的,每次送外卖不超过10个地方,给你这些地方之间的时间,求送完外卖回到店里的总时间最小。

最近有点sb,经常犯sb的错误,今天又是,蛋疼啊。这题很明显的dp,dp[i][j]:表示在i状态(用二进制表示城市有没有经过)时最后到达j城市的最小时间,转移方程:dp[i][j]=min(dp[i][k]+d[k][j],dp[i][j])  d[k][j]是k城市到j城市的最短距离,显然要先用flody处理一下。

Run ID User Problem Result Memory Time Language Code Length Submit Time
9212959 201030720425 3311 Accepted 212K 0MS C++ 995B 2011-08-22 19:25:49

代码

#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<iostream>
using namespace std;
int d[11][11],n,m,dp[1<<11][11];
const int inf=1<<30;
void flody()
{
	for(int k=0;k<n+1;k++)
		for(int i=0;i<n+1;i++)
			for(int j=0;j<n+1;j++)
			{
				if(d[i][k]+d[k][j]<d[i][j])
					d[i][j]=d[i][k]+d[k][j];
			}
}
void DP()
{
	int ans=inf;
	for(int i=0;i<(1<<n);i++)
		for(int j=1;j<n+1;j++)
			if(i==(1<<(j-1)))
				dp[i][j]=d[0][j];
			else
				if(i&(1<<(j-1)))
				{			
					dp[i][j]=inf;
					for(int k=1;k<n+1;k++)
						if(k!=j&&(i&(1<<(k-1))))
							dp[i][j]=min(dp[i^(1<<(j-1))][k]+d[k][j],dp[i][j]);
				}
				for(int i=1;i<n+1;i++)
				{
					ans=min(ans,dp[(1<<n)-1][i]+d[i][0]);
				}
				printf("%d\n",ans);
}
int main()
{
	while(1)
	{
		scanf("%d",&n);
		if(n==0)break;
		for(int i=0;i<n+1;i++)
			for(int j=0;j<n+1;j++)
			{
				scanf("%d",&d[i][j]);
			}
			flody();
			DP();
	}
	return 0;
}

抱歉!评论已关闭.