UVa1347旅行

news/2025/2/11 18:56:15/

题意:n个点,坐标给出,设计一条路线,从最左边的点,走到最右边的点,再回来,除最左边的点和最右边的点外,每个点有且经过一次。求最短距离。
分析:
转换一下思路,不是一个人在走,而是两个人从同一起点出发,走不同的两条路,在终点相遇。假设两个人是 i, j,这样可以定义状态 d[i][j] :一个在 i ,一个在 j ,离终点 n 还要多少距离。
但是有一个问题,很难知道下一个要走的点是否被另一个人走过,需要修改状态的定义。
修改一下:d(i,j):1 到max(i,j) 都已经走过了,且两人现在的位置是 i , j。可以看到 d(i,j)=d(j,i)。只是人换了一下而已。既然这样,就规定一下 i > j,这样可以不重复。那么对于当前状态d(i,j),下一个要走的点只能 > i(i+1, i+2…因为i 以下的都走过了)。比如现在A在 i 位置, B 在 j 位置,下一个可能的状态有两个:
A走一步到 i+1, B不动。 d[ i+1 ][ j ] + dis( i , i+1 )
A不动,B走两步到 i+1。 d[ i ][ i+1 ] + dis( j, i+1 )
由于上面规定 i > j,所以第二个状态可以改为 d[ i+1 ][ i ]。
转移方程:d[ i ][ j ] = min( d[ i+1 ][ j ] + dis( i, i+1 ), d[ i+1 ][ i ] + dis( j, i+1 ) ).

边界条件:
d[ n-1 ][ j ] = dis( n-1, n) + dis( j, n ). ( 1<= j< n-1). 因为A走到n-1位置时,<=n-1的位置都已经走过了,所以在其他位置 j 只能直接走到 n.

记忆化搜索代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 1<<30;
const int N = 1000+5;
struct Point{double x,y;
}P[N];
double dis(int a, int b){return sqrt((P[a].x-P[b].x)*(P[a].x-P[b].x) + (P[a].y-P[b].y)*(P[a].y-P[b].y));
}
double d[N][N];double solve(int i, int j){if(d[i][j] > 0) return d[i][j];else return d[i][j] = min(solve(i+1,j) + dis(i,i+1), solve(i+1,i)+dis(j,i+1));
}int main()
{int n; //freopen("in.txt","r",stdin);while(scanf("%d",&n) == 1&&n){for(int i = 1; i <= n; ++i) scanf("%lf %lf",&P[i].x,&P[i].y);// 初始化 memset(d,0,sizeof(d));for(int i = 1; i < n-1; ++i) d[n-1][i] = dis(n-1,n) + dis(i,n); // 规划 solve(2,1);printf("%.2lf\n",d[2][1]+dis(1,2));}//fclose(stdin);return 0;
}

递推:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;const int N = 1000+5;
struct Point{double x,y;
}P[N];
double dis(int a, int b){return sqrt((P[a].x-P[b].x)*(P[a].x-P[b].x) + (P[a].y-P[b].y)*(P[a].y-P[b].y));
}
double d[N][N];int main()
{int n; //freopen("in.txt","r",stdin);while(scanf("%d",&n) == 1&&n){for(int i = 1; i <= n; ++i) scanf("%lf %lf",&P[i].x,&P[i].y);if(n == 1){ printf("%.2lf\n",0); continue; }if(n == 2){ printf("%.2lf\n",dis(1,2)); continue; }// 初始化 for(int i = 1; i < n-1; ++i) d[n-1][i] = dis(n-1,n) + dis(i,n); // 规划 for(int i = n-2; i >= 2; --i){for(int j = 1; j < i; ++j){d[i][j] = min(d[i+1][i]+dis(j,i+1), d[i+1][j]+dis(i,i+1));}}printf("%.2lf\n",d[2][1]+dis(1,2));}//fclose(stdin);return 0;
}

http://www.ppmy.cn/news/191688.html

相关文章

14年macmini装双硬盘_2011中Mac Mini详尽拆解 可装两块硬盘

前言&#xff1a;ifixit这位拆解专业户在苹果发布了2011年中款的MacBook Air和Mac Mini这个时候&#xff0c;自然是不会闲着的。这不分解完了新版的MacBook Air之后&#xff0c;新版的Mac Mini也在ifixit的拆解大师们的手下&#xff0c;被细细分解。 第一步&#xff1a; 我们(i…

uva-1347

题目链接&#xff1a;https://vjudge.net/problem/UVA-1347 题意&#xff1a;有n个点&#xff0c;给出x、y坐标。找出一条路&#xff0c;从最左边的点出发&#xff0c;严格向右走到达最右点再严格向左回到最左点。问最短路径是多少&#xff1f; 不看题解我是真的不知道这个题可…

mini计算机结构,简单拆机看内部构造_苹果 Mac mini MGEN2CH/A_台式电脑评测-中关村在线...

从整个外观设计来看,新Mac mini的变化确实不大,仅仅是在接口配置与布局方面有所不同,而内部变化在先前的拆机中有所展示,当然在此还是有必要重新梳理一边。首先新Mac mini的底盖圆盘的固定方式较之上一代产品有所改变,原先旋钮式固定方式变更为卡扣式固定,因此拆机时需要…

Mac Mini换固态硬盘

新年新气象&#xff0c;今天来把mini升级下&#xff0c;换个固态硬盘。 mini型号&#xff1a; A1347 &#xff0c; 2013版 材料&#xff1a; 固态硬盘一个&#xff0c;螺丝刀一套(里面需包含六角T6、T8和M2的螺丝刀)&#xff0c;U盘一个&#xff0c;拨片一个。如图&#xff1a;…

UVA1347 旅行

UVA1347 旅行 题目大意 给定 n n n 个点 ( x i , y i ) (x_i,y_i) (xi​,yi​)&#xff0c;从最左边的点出发到达最右边&#xff0c;再返回最左边&#xff0c;要求经过的点不重复且覆盖所有的点&#xff0c;求最小路径长&#xff08;两点的距离定义为欧几里得距离&#xff…

P1347 排序

题目描述 一个不同的值的升序排序数列指的是一个从左到右元素依次增大的序列&#xff0c;例如&#xff0c;一个有序的数列 A,B,C,DA,B,C,D 表示A<B,B<C,C<DA<B,B<C,C<D。在这道题中&#xff0c;我们将给你一系列形如 A<BA<B 的关系&#xff0c;并要求你…

mac mini php开发,苹果就不让你升级!新版mac mini真机详细拆解+解析(图)

历经两年多的沉默&#xff0c;小巧可爱的Mac mini终于升级了&#xff0c;带来了Intel Haswell处理器、Iris/HD5000核芯显卡、802.11ac Wi-Fi无线网卡、PCI-E固态硬盘等闪亮配置(不同型号不一样)&#xff0c;这些都是让人欣喜的地方。 但事实上&#xff0c;新款Mac mini处处都存…

第12章_数据库其它调优策略

第12章_数据库其它调优策略 1. 数据库调优的措施 1.1 调优的目标 尽可能 节省系统资源 &#xff0c;以便系统可以提供更大负荷的服务。&#xff08;吞吐量更大&#xff09; 合理的结构设计和参数调整&#xff0c;以提高用户操作 响应的速度 。&#xff08;响应速度更快&…