牛客 - 收集纸片(最短哈密顿路径-状压dp)

题目链接:点击查看

题目大意:给出一个 n * m 的二维平面,其中有 k 个纸片,给出第一个纸片的位置,要求从第一个纸片出发,经过每个纸片一次后再回到第一个纸片的位置,输出最短路径

题目分析:最短哈密顿路径的模板题,比赛的时候为什么没看出来呢。。好像是被 n * m 很小所迷惑了,感觉像是一道搜索题,但想了半天没什么思路就不想做了,赛后回顾一下的时候发现,k 给的特别小,最大只有 11 ,而且题目的条件又完全符合哈密顿路径的性质,只不过要求起点和终点重合,那么我们只需要最后对每个状态维护一下到起点的最小值就好了

代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
     
typedef long long LL;
    
typedef unsigned long long ull;
     
const int inf=0x3f3f3f3f;

const int N=1e5+100;

struct Point
{
	int x,y;
}point[15];

int d[15][15],dp[(1<<11)+100][15];

int dis(int x,int y)
{
	return abs(point[x].x-point[y].x)+abs(point[x].y-point[y].y);
}

int main()
{
#ifndef ONLINE_JUDGE
//    freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
#endif
//  ios::sync_with_stdio(false);
   	int w;
   	cin>>w;
   	while(w--)
   	{
   		int n,m;
   		scanf("%d%d",&n,&m);
   		scanf("%d%d",&point[0].x,&point[0].y);
   		int k;
   		scanf("%d",&k);
   		for(int i=1;i<=k;i++)
   			scanf("%d%d",&point[i].x,&point[i].y);
   		for(int i=0;i<=k;i++)
   			for(int j=0;j<=k;j++)
   				d[i][j]=dis(i,j);
   		memset(dp,inf,sizeof(dp));
   		dp[1][0]=0;
   		for(int i=0;i<(1<>j)&1)
   				{
   					for(int t=0;t<=k;t++)
   					{
   						if((i>>t)&1)
   							continue;
   						dp[i|(1<

 

你可能感兴趣的:(状压dp,动态规划)