ACwing91 最短Hamilton路径 状压dp

网址:https://www.acwing.com/problem/content/93/

题解:

状压之后暴力枚举更新。$dp[i][j]$表示$i$的二进制数中1的位置就是会经过的点,$j$的位置是当前的点。则转移方程是$dp[i][j]=min(dp[i][j],dp[i\oplus (1<<j)][k]+dis[k][j])$,其中$i\oplus (1<<j)$是二进制状态$i$去掉第$j$条边,即从一个没有与$j$直接连边的状态从$k$到$j$进行松弛,最后判断一下有边才进行枚举就好了。如果不状压,就会$TLE$。

AC代码:

#include <bits/stdc++.h>
using namespace std;
int mp[20][20];
int f[1 << 20][20];
int solve(int n)
{
	memset(f, 0x3f3f3f3f, sizeof(f));
	f[1][0] = 0;
	for (int i = 1; i < (1 << n); ++i)
		for (int j = 0; j < n; ++j)
			if ((i >> j) & 1)
				for (int k = 0; k < n; ++k)
					if (((i ^ (1 << j)) >> k) & 1)
						f[i][j] = min(f[i][j], f[i ^ (1 << j)][k] + mp[k][j]);
	return f[(1 << n) - 1][n - 1];
}
int main()
{
	int n;
	scanf("%d", &n);
	for (int i = 0; i < n; ++i)
		for (int j = 0; j < n; ++j)
			scanf("%d", &mp[i][j]);
	printf("%d\n", solve(n));
	return 0;
}

  

原文地址:https://www.cnblogs.com/Aya-Uchida/p/11470582.html

时间: 2024-10-30 10:58:26

ACwing91 最短Hamilton路径 状压dp的相关文章

完全图的最短Hamilton路径——状压dp

题意:给出一张含有n(n<20)个点的完全图,求从0号节点到第n-1号节点的最短Hamilton路径.Hamilton路径是指不重不漏地经过每一个点的路径. 算法进阶上的一道状压例题,复杂度为O(n^2 * 2^n),还是蛮恐怖的. 设f[i][j]表示当前经过状态为i,且当前在点j所花费的最小代价.其中i是二进制压缩值,从0-n-1位分别表示这个点是否经过了.目标状态为f[2^n - 1][n - 1],那么我们从小到大枚举i,再循环枚举当前点j和上一个状态所在的点k即可. 转移方程:f[i,

最短Hamilton路径-状压dp解法

最短Hamilton路径 时间限制: 2 Sec  内存限制: 128 MB 题目描述 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次. 输入 第一行一个整数n. 接下来n行每行n个整数,其中第i行第j个整数表示点i到j的距离(一个不超过10^7的正整数,记为a[i,j]). 对于任意的x,y,z,数据保证 a[x,x]=0,a[x,y]=a

Contest Hunter 0103 最短Hamilton路径 - 状压DP

传送门 思路: 1.状态:由于经过的点是一个集合,所以我们用dis[i][j]表示经过的点的状态为i,且当前位于点j时的最短Hamilton路径,其中i为一个二进制整数,用来存储经过的点的情况.为了方便位运算,我们的点的标号为0~n-1. 2.边界:dis[1][0]表示当前在起点0的最短Hamilton路径. 最终答案在dis[(1<<n)-1][n-1],即0~n-1所有点都被经过了一遍,当前在终点n-1的最短Hamilton路径. 3.决策:对于两点i,j,有两种决策:一是直接通过当前求

Acwing-91-最短Hamilton路径(状压DP)

链接: https://www.acwing.com/problem/content/93/ 题意: 给定一张 n 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次. 思路: 用二进制枚举哪些点被经过了.同时枚举经过的点j,再枚举经过点j之前的点k. 得到Dp[i][j] = min(Dp[i][j], Dp[lasti][k]+Len[k][j]).其中i对应经过点j

『最短Hamilton路径 状态压缩DP』

状压DP入门 最短Hamilton路径 Description 给定一张 n(n≤20) 个点的带权无向图,点从 0~n-1 标号,求起点 0 到终点 n-1 的最短Hamilton路径. Hamilton路径的定义是从 0 到 n-1 不重不漏地经过每个点恰好一次. Input Format 第一行一个整数n. 接下来n行每行n个整数,其中第i行第j个整数表示点i到j的距离(一个不超过10^7的正整数,记为a[i,j]). 对于任意的x,y,z,数据保证 a[x,x]=0,a[x,y]=a[y

P1171 售货员的难题 - 状压DP【最短Hamilton路径】

P1171 售货员的难题 Sol: 最短Hamilton路径,经典的NPC问题,小数据可以通过状压DP 实现. 状态:\(f[i][j]\)表示当前在第i号点,且已经过的点的状态为j 时的最短Hamilton路径. 阶段:若以点为阶段,由于会从点i转移到点i+1,还可能从i+1转移到i-1,不具有无后效性,因此我们考虑以二进制状态为阶段进行转移. 决策:考虑由哪一个点转移而来. 转移:\(f[i][j]=\max \limits_{i\&(1<<i)\&\&i\&

状压DP HDU3538 A sample Hamilton path

A sample Hamilton path Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 527    Accepted Submission(s): 213 Problem Description Give you a Graph,you have to start at the city with ID zero. Input T

Codeforces 453B Little Pony and Harmony Chest:状压dp【记录转移路径】

题目链接:http://codeforces.com/problemset/problem/453/B 题意: 给你一个长度为n的数列a,让你构造一个长度为n的数列b. 在保证b中任意两数gcd都为1的情况下,使得 ∑|a[i]-b[i]|最小. 让你输出构造的数列b. (1<=n<=100, 1<=a[i]<=30) 题解: 因为1<=a[i]<=30,所以有1<=b[i]<=60,此时才有可能最优. 因为b中任意两数gcd为1,所以对于一个质因子p[i]

最短Hamilton路径 数位dp

最短Hamilton路径 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 21; 4 int dp[1<<maxn][maxn]; 5 int maps[maxn][maxn]; 6 int main() { 7 int n; cin >> n; 8 for (int i = 0; i < n; i++) 9 for (int j = 0; j < n; j++) 10