P1433 吃奶酪

  1. 原题链接:

P1433 吃奶酪 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

  1. 算法 思路:

这个题的大意就是让我们从00点出发,遍历所有点,求一个最短路径,这不是一个图的问题,因为边是任意的,所以会首先想到dfs搜索就行了,

剪枝:使用一个ans保留过程中的答案,如果某条道路还没走完就已经比结果大了,直接返回。

当做到这一步时,会发现有案例会TLE,说明还要进一步剪枝。

需要考虑:同样的几个点, 例如 1 3 5 , 从 0 到 1 3 5 ,从 0 到 3 5 1....都是道路,但是这些道路里面有长的有短的,我们不要每次都要走一遍,所以就要保存一个每个具体道路的最短路。具体的方法是通过:状态压缩 来 保存。

具体解释可见:P1433 吃奶酪题解 - 糖豆爸爸 - 博客园 (cnblogs.com)

  1. AC Code:

#include<bits/stdc++.h>
using namespace std;
const int N =16;
double pt[N][2];
int v[N];
int n;
double ans  = DBL_MAX;

double dp[1<<N][N];
double dis[N][N];

void dfs(int k,double temp,int f,int pass){
    if(temp>ans)return;
    if(k==n){
        ans =min(ans,temp);
        return;
    }
    for(int i =1;i<=n;i++){
        int tt = pass+ (1<<(i-1));
        double d = dis[i][f];
        if(dp[tt][i] && dp[tt][i]<= temp+d)continue;
        if(!v[i]){
            v[i] = 1;
            dp[tt][i] = temp+ d;
            dfs(k+1,temp+d,i,tt);
            v[i] =0;
        }
    }
}
int main(){
    cin>>n;
    for(int i =1;i<=n;i++)cin>>pt[i][0]>>pt[i][1];
    for(int i =0;i<=n;i++)
        for(int j =i+1;j<=n;j++)
            dis[i][j] = dis[j][i] = sqrt(pow(pt[i][0]-pt[j][0],2)+pow(pt[i][1]-pt[j][1],2));
    dfs(0,0.0,0,0);
    printf("%.2f",ans);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值