https://www.luogu.com.cn/problem/P1171
经典的旅行商问题
dp[i][j]表示从j出发,去遍历状态为i的点,并且回到起点的最短路径长度
初始化:dp[0][i]=dis(i,起点),即从点i哪儿哪儿也不遍历,直接回到起点的路径长度
对于每一个状态i,枚举要从哪个点出发,去遍历这个状态
然后枚举这个点要直接前往的状态中的某个点
最后输出dp[总状态-起点状态][起点] (从起点出发,遍历除起点外所有点,再回到起点)
#include<cstdio> #include<algorithm> using namespace std; #define N 21 int dis[N][N],dp[1<<N][N]; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) scanf("%d",&dis[i][j]); int m=(1<<n)-1; for(int i=1;i<=m;++i) for(int j=1;j<=n;++j) dp[i][j]=1e9; for(int i=1;i<=n;++i) dp[0][i]=dis[i][1]; for(int i=1;i<m;++i) for(int j=1;j<=n;++j) if(!(1<<j-1&i)) for(int k=1;k<=n;++k) if(1<<k-1&i) dp[i][j]=min(dp[i][j],dis[j][k]+dp[1<<k-1^i][k]); printf("%d",dp[m-1][1]); }
题目背景
数据有更改
题目描述
某乡有nnn个村庄(1<n≤201<n \le 201<n≤20),有一个售货员,他要到各个村庄去售货,各村庄之间的路程s(0<s<1000)s(0<s<1000)s(0<s<1000)是已知的,且AAA村到BBB村与BBB村到AAA村的路大多不同。为了提高效率,他从商店出发到每个村庄一次,然后返回商店所在的村,假设商店所在的村庄为111,他不知道选择什么样的路线才能使所走的路程最短。请你帮他选择一条最短的路。
输入格式
村庄数nnn和各村之间的路程(均是整数)。
输出格式
最短的路程。
输入输出样例
3
0 2 1
1 0 2
2 1 0
3
说明/提示
输入解释
333 {村庄数}
0210 2 1 021 {村庄111到各村的路程}
1021 0 2102 {村庄222到各村的路程}
2102 1 0 210 {村庄333到各村的路程}