Tour UVA - 1347 dp

传送门


题目大意:给定n个坐标(x,y),按照x地等的顺序给出, 并且保证x都不相同,均为正整数。你的任务是设计一条路线,从最左侧出发,达到最右侧, 再返回最左侧那个点,所有点恰好经过一次。并且总路线距离长度最短。


解题思路:可以认为从左左侧有两个人出发,每个人除了最左侧和最右侧的点外不会走相同的点,假设两个人走到的点分别为i, j(横坐标x)。dp(i, j)表示从1~max(i, j)的点都走过。dist表示距离最右侧的点的距离。那么每走一个点都有两个状态,在i的人走到下一个还是在j的走到下一个,由于不好判断下一个的坐标,并且dp(i, j) == dp (j, i), 因此我们不妨让i总是大于j。 那么下一个坐标就是i+1; 两个状态分别为, 走在前面的到达下一个点 dp(i+1, j), 或者走在后面的到下一个dp(i+1, i)。(解释:最大的肯定时i+1, 所以不管怎么走都是 dp(i, x), 如果走在前面的那个人走, 那么小的那个人还是在j, 如果在后面的到达i+1, 那么后面的人就变成了在i的那个人)。


AC代码:

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>

using namespace std;

double distance(int x1, int y1, int x2, int y2)
{
	double x = fabs(x1-x2);
	double y = fabs(y1-y2);
	return sqrt(x*x + y*y);
}

int X[1050], Y[1050];
double dist[1050][1050];
int n;

double dp(int i, int j)
{
	if(dist[i][j] > 0) return dist[i][j];
	if(i >= n-1) return dist[i][j] = distance(X[n-1], Y[n-1], X[j], Y[j]);

	return dist[i][j] = min(dp(i+1, j)+distance(X[i+1], Y[i+1], X[i], Y[i]), dp(i+1, i)+distance(X[i+1], Y[i+1], X[j], Y[j]));
}

int main()
{
	while(scanf("%d", &n) != EOF && n)
	{
		memset(dist, 0, sizeof(dist));
		for(int i=0; i<n; i++)
			scanf("%d%d", &X[i], &Y[i]);
		printf("%.2f\n", dp(0, 0));
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值