0
点赞
收藏
分享

微信扫一扫

洛谷 P1433 吃奶酪 状态压缩DP

爱做梦的夏夏 2022-02-11 阅读 64

练习动态规划中

本题参考博客:

P1433 吃奶酪 (状压dp)

洛谷 普及组 P1433 吃奶酪

原题链接:洛谷 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;
}


举报

相关推荐

0 条评论