站外题求助
  • 板块学术版
  • 楼主CH_mengxiang
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/2/28 15:09
  • 上次更新2023/10/23 23:31:28
查看原帖
站外题求助
190485
CH_mengxiang楼主2023/2/28 15:09

题目描述(POJ3311):

披萨店以尽可能快地向顾客提供披萨而自豪。司机将等待一个或多个(最多10个)订单被处理,然后开始送 货。他愿意走最短的路线运送这些货物,然后返回比萨店,即使这意味着途中要经过相同的地点或披萨店不止一次。

输入: 输入包含多个测试用例。每个测试用例的第1行都包含一个整数n (1≤n ≤10),表示要交付的订单数量。之后n +1行中的每一行都包含n +1个整数,表示披萨店(编号0)和n 个位置(编号为1~n)之间的行程时间。第i 行上的第j 个值表示从位置i 直接到位置j 的时间,时间值可能不对称,即从位置i 直接到位置j 的时间可能与从位置j 直接到位置i 的时间不同。n =0时将终止输入。

输出: 对每个测试用例,都单行输出交付所有披萨并返回披萨店的最短时间。

POJ3311链接

#include<iostream>
#include<cstring>
using namespace std;
const int INF=0x3f3f3f3f;
int g[11][11],dp[1<<10][11],n;
void floyd()//弗洛伊德求最短路 
{
	for (int k=0;k<n;k++)
	  for (int i=0;i<n;i++)
	    for (int j=0;j<n;j++)
		  g[i][j]=min(g[i][j],g[i][k]+g[k][j]);
}
void Traveling()//递推求dp[s][u] 
{
	memset(dp,0x3f,sizeof(dp));
	dp[(1<<n)-1][0]=0;
	for (int s=(1<<n)-2;s>=0;s--)
	  for (int u=0;u<n;u++)
	    for (int v=0;v<n;v++)
	    {
	    	if (!(s>>u&1)&&u!=0) continue;
	    	if (!(s>>v&1)&&dp[s][u]>dp[s|1<<v][v]+g[u][v])
	    	  dp[s][u]=dp[s|1<<v][v]+g[u][v];
		}
}
int main()
{
	while (1)
	{
		cin>>n;
		if (!n) break;
		n++;
		for (int i=0;i<n;i++)
		  for (int j=0;j<n;j++)
		    cin>>g[i][j];
		floyd();
		Traveling();
		cout<<dp[0][0]<<endl;
	}
	return 0;
}

用的状压DP,一直RE,有时还会莫名奇妙的CE

2023/2/28 15:09
加载中...