Tour UVA - 1347(dp二个决策)

Tour UVA - 1347

题意:

给你n个点(按照x的递增序列给出),你的目标是从设计一条路线,从最左边的点出发,之后到达最右边的点,之后再返回。要求除了最左点和最右的点,每个点只经过一次。

思路:

  1. d ( i , j ) d(i,j) d(i,j)表示1~ m a x ( i , j ) max(i,j) max(i,j)全部走过,且两个人的当前位置分别是 i i i j j j,还需要走多长的距离。
  2. 不难发现 d ( i , j ) = d ( j , i ) d(i,j)=d(j,i) d(i,j)=d(j,i),因此从现在开始规定在状态中 i > j i>j i>j。这样,不管是哪个人,状态 d ( i , j ) = m i n ( d ( i + 1 , j ) , d ( i + 1 , i ) ) d(i,j)=min(d(i+1,j),d(i+1,i)) d(i,j)=min(d(i+1,j),d(i+1,i))
  3. 边界是 d ( n − 1 , j ) = d i s t ( n − 1 , n ) + d i s t ( n , j ) d(n-1,j)=dist(n-1,n) +dist(n,j) d(n1,j)=dist(n1,n)+dist(n,j)
  4. ans = d i s t ( 1 , 2 ) = d ( 2 , 1 ) dist(1,2)=d(2,1) dist(1,2)=d(2,1)

AC

#include <iostream>
#include <bits/stdc++.h>
#define For(i,x,y) for(int i=(x); i<=(y); i++)
#define fori(i,x,y) for(int i=(x); i<(y); i++)
#define rep(i,y,x) for(int i=(y); i>=(x); i--)
#define mst(x,a) memset(x,a,sizeof(x))
#define pb push_back
#define sz(a) (int)a.size()
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int>pa;
typedef pair<ll,ll>pai;
struct point{
    int x, y;
} p[1010];
const int INF = 0x3f3f3f3f;
double d[1010][1010];
int n;
double dist(point p1, point p2){
    double res = sqrt((p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y));
    return res;
}
double dp(int i, int j){
    double& ans = d[i][j];
    if(ans != INF)return ans;
    if(i == n-1)return dist(p[n-1],p[n])+dist(p[n],p[j]);
    else return ans = min(dp(i+1,j) + dist(p[i],p[i+1]), dp(i+1,i) + dist(p[j],p[i+1]));
}
int main()
{
    while(~scanf("%d", &n)){
        For(i,0,n)For(j,0,n) d[i][j] = INF;
        For(i,1,n) scanf("%d%d", &p[i].x, &p[i].y);
        double ans = dp(2,1) + dist(p[1],p[2]);
        printf("%.2f\n", ans);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值