URAL 1143 Electric Path

( http://www.elijahqi.win/2017/12/30/ural-1143-electric-path/)
Background
At the team competition of the 10th national student informatics Olympic, which is organized at Hanoi National University, there are N teams participating. Each team is assigned to work in a camp. On the map, it can be seen that the camps are positioned on the vertices of a convex polygon with N vertices: P1, P2, …, PN (the vertices are enumerated around the polygon in counter-clockwise order.) In order to achieve absolute safety providing electricity to the camps, besides an electric supplying system, the host organization set up a path from a reserved electricity generator (which is placed in one of the camps) to every camp once, and the path’s total length is minimum.
Problem
Given the coordinates of the polygons’ vertices (the camps’ positions), determine the length of the electric path corresponding to the host organization’s arrangement.
Input
The first line contains the integer N (1 ≤ N ≤ 200). The i’th line of the next N lines contains two real numbers xi, yi, separated by a space, with no more than 3 digits after the decimal points, are vertex Pi’s coordinates on the plane (with i = 1, 2, …, N). The length of the path connecting two vertex (xi, yi) and (xj, yj) is computed with the formula: sqrt((xi − xj)2 + (yi − yj)2).
Output
The only line should contain real number L (written in real number format, with 3 digits after the decimal point), which is the total length of the electric path.
Sample
input output

4
50.0 1.0
5.0 1.0
0.0 0.0
45.0 0.0

50.211

强啊 还是icefox最强啦qwq %%%这些dp题我哪会啊
题意:求一个凸包上哈密尔顿距离最小是多少 那么不是所有边都连是最好的 比如 四个点 我可以连成z字形状 且因为这是凸包上的最短哈密顿路径 所以一定不能相交 那么就可以考虑dp来解决了 如何搞?
设dp[i][l][0/1]表示 我当前正好要做的区间是i~i+l-1 求问这一段的哈密顿距离最小是多少
那么显然我这个dp方程有两种转移 有可能我是i+1~i+l-1—->i~i+l-1 或者是i~i+l-2—->i~i+l-1
然后分类讨论一下即可
dp[0][i][len]=min(dp[0][i+1][len−1]+dis[i][i+1],dp[1][i+1][len−1]+dis[i][i+len−1]);
dp[1][i][len]=min(dp[1][i][len−1]+dis[i+len−1][i+len−2],dp[0][i][len−1]+dis[i][i+len−1]);
答案为min{dp[0][i][n]|1≤i≤n}复杂度是O(n2)的


#include<cmath>
#include<cstdio>
#include<algorithm>
#define N 220
using namespace std; 
double x[N],y[N],dp[N][N][2],dis[N][N];int n;
//dp表示从i开始长度为len的最短哈密尔顿距离是多少 
//0表示在左端 1表示在右端 
int main(){
    freopen("ural1143.in","r",stdin);
    scanf("%d",&n);
    for (int i=0;i<n;++i) scanf("%lf%lf",&x[i],&y[i]);
    for (int i=0;i<n;++i)
        for (int j=0;j<n;++j) dis[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
    for (int l=2;l<=n;++l){
        for(int i=0;i<n;++i){
            dp[i][l][0]=min(dp[(i+1)%n][l-1][0]+dis[i][(i+1)%n],dp[(i+1)%n][l-1][1]+dis[i][(i+l-1)%n]);
            dp[i][l][1]=min(dp[i][l-1][1]+dis[(i+l-2)%n][(i+l-1)%n],dp[i][l-1][0]+dis[i][(i+l-1)%n]);
        }
    }double ans=1LL<<60;
    for (int i=0;i<n;++i) ans=min(ans,dp[i][n][0]);printf("%.3f",ans);
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值