Description
某乡有n个村庄,有一个售货员,他要到各个村庄去售货,各村庄之间的路程s是已知的,且A村到B村与B村到A村的路大多不同。为了提高效率,他从商店出发到每个村庄一次,然后返回商店所在的村,假设商店所在的村庄为1,他不知道选择什么样的路线才能使所走的路程最短。请你帮他选择一条最短的路。
Input
村庄数n和各村之间的路程(均是整数)。
Output
最短的路程
Sample Input
3 //村庄数
0 2 1 //村庄1到各村的路程
1 0 2 //村庄2到各村的路程
2 1 0 //村庄3到各村的路程
Sample Output
3
HINT
题解
这道题看上去是搜索 ,但看了数据范围后…
后来才知道要用状态压缩DP
这也算是我状态压缩DP的第一题吧
代码
#include <cstdio>
#include <algorithm>
#include <cstring>
const int inf=2000000000;
int dist[20][20];//dist代表村庄之间的距离
int n,i,j,k,ans;
int f[20][40009];
int main()
{
scanf("%d",&n);
for (i=1;i<=n;i++)
{
for (j=1;j<=n;j++)
{
scanf("%d",&dist[i][j]);
}
}
memset(f,63,sizeof(f));
ans=inf;
f[1][1]=0;
for (i=0;i<=(1<<n)-1;i++)//枚举状态
{
for (j=1;j<=n;j++) //枚举当前村庄
{
if ((i&(1<<(j-1)))!=0) //如果当前村庄没走过
{
for (k=1;k<=n;k++)//枚举前一个村庄
{
if (j!=k)
{
if (i&(1<<(k-1)))//如果前一个村庄走过
{
f[j][i]=std::min(f[j][i],f[k][i-(1<<(j-1))]+dist[k][j]);//取值(位运算真的很强)
}
}
}
}
}
}
for (i=1;i<=n;i++)
{
ans=std::min(ans,f[i][(1<<n)-1]+dist[i][1]);//枚举回第一个点的路程
}
printf("%d\n",ans);
return 0;
}