练习动态规划中
本题参考博客:
原题链接:洛谷 P1433 吃奶酪
#include <bits/stdc++.h>
using namespace std;
double x[16],y[16],d[16][16],dp[16][40000];
double dis(int a,int b)
{
return sqrt( (x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]) );
}
int main()
{
std::ios::sync_with_stdio(false);
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>x[i]>>y[i];
}
memset(dp,127,sizeof(dp));//初始化点在各种状态下的距离
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
d[i][j]=d[j][i]=dis(i,j);
}
}
//第i点到(0,0)的距离,状态为1<<(i-1)
for(int i=1;i<=n;i++)
{
dp[i][1<<(i-1)]=dis(0,i);
}
for(int r=1;r<=(1<<n)-1;r++)//遍历所有状态
{
for(int now=1;now<=n;now++)
{
if((r&(1<<(now-1)))==0)
continue;//跳过未访问的点
for(int pre=1;pre<=n;pre++)
{
if((r&(1<<(pre-1)))==0 ||now==pre)
continue;//如果pre不在当前状态已经走过的点当中或者now和pre是同一个点,就跳过
dp[now][r]=min(dp[now][r],dp[pre][r-(1<<(now-1))]+d[now][pre]);
}
}
}
double res=1e8;
for(int i=1;i<=n;i++)
{
res=min(dp[i][(1<<n)-1],res);
}
cout<<setiosflags(ios::fixed)<<setprecision(2)<<res<<endl;
return 0;
}