• [Codeforces 30D] Kings Problem


    Brief Intro:

    有n+1个点,其中n个点在X轴上,求从第k个点出发最短的汉密尔顿路径

    Solution:

    分类讨论+逐个枚举

    设dist(i)是第i个点到n+1的距离

    cal1(l,r)是n+1到dat[l]~dat[r]的最短距离

    cal2(l,r)是dat[k]到dat[l]~dat[r]再到n+1的最短距离

    1、如果k=n+1,则答案明显是线段长+min(dist(1),dist(n))

    2、否则要逐个枚举

    可以发现共有2种可能:n+1连到线段的边有1条/2条

    如为1条,则结果为cal1(1,n);

    如为2条,则可将路径分为dat[k]到dat[l]~dat[r]再到n+1  +  n+1到剩余的点

    明显剩余的点连续时有最优解

    于是res[i]=min( cal1(1,i-1)+cal2(i,n) , cal2(1,i-1)+cal1(i,n) )。

    Code:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int MAXN=1e5+10;
    double dat[MAXN],x,y,kx;
    int n,k;
    
    double dist(int pos){return hypot(x-dat[pos],y);}
    
    double cal1(int l,int r)
    {
        return dat[r]-dat[l]+min(dist(l),dist(r));
    }
    
    double cal2(int l,int r)
    {
        return dat[r]-dat[l]+min(dist(l)+fabs(kx-dat[r]),dist(r)+fabs(kx-dat[l]));
    }
    
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++) scanf("%lf",&dat[i]);
        scanf("%lf%lf",&x,&y);
        
        kx=dat[k];sort(dat+1,dat+n+1);
        
        double res;
        if(k==n+1) res=cal1(1,n);
        else
        {
            res=cal2(1,n);
            for(int i=2;i<=n;i++)
                res=min(res,min(cal1(1,i-1)+cal2(i,n),cal2(1,i-1)+cal1(i,n)));
        }
        printf("%.10f",res);
        return 0;
    }
  • 相关阅读:
    SpringBoot之使用外部的启动类
    CCF——最小差值(2017-12)
    CCF——买菜(2018-09)
    CCF——卖菜(2018-09)
    2792. Grammar Lessons
    2756. Lucky Transformation
    2776. String Task
    2794. Petya and Strings
    2810. Palindromic Times
    14. Football
  • 原文地址:https://www.cnblogs.com/newera/p/9086692.html
Copyright © 2020-2023  润新知