zoukankan      html  css  js  c++  java
  • Tour UVa 1347 (DAG)

    本题难在设置状态表示。

    题目要求先从左到右,再从右到左沿x轴方向经历坐标系上的点(1~n点),可以考虑成两条路径,分别从最左到最右,分别经历不同点且不能重合(除了起点和终点)。可以想到用$d(i,j)$表示一条路走到了$i$,一条路走到了$j$。因为两条路加起来要cover路径上所有点,所以$d(i,j)$可以表示$max(i,j)$和之前的点已经全被走过,还需走多远才能满足条件。因为两条路没有优劣,所以$d(i,j)==d(j,i)$,为了方便操作,可以规定要求$i>j$。可以用例子来理解:第一个人走到2,第二个人就只能停在1了,第一个人走到3,第一个人可以走到1或者2,第一个人走到4,第一个人可以走到1,2,3,始终让$i>j$可以满足结构的清晰。也就是说,$i$决定自己已经走到了最远的地方,而此时$j$停留在哪个地方,来保证$i$及以前的地方全部都被走过(可以理解为$j$给$i$擦屁股)。当$i$到达n时,$j$可以在路上$(1 ~ n-1)$中任何点,因为它走的是$i$走剩的点,所以$d(n,j)=0$。而状态方程可以写为:$d(i,j)=min[d(i+1,j)+dist(i,i+1),d(i+1,i)+dis(j,i+1)]$,其中$dist(a,b)$表示$a,b$之间的距离。

    边界条件:当$i$到达n时,$j$可以在路上$(1 ~ n-1)$中任何点,因为它走的是$i$走剩的点,所以$d(n,j)=0$。(这个边界条件是错误的,因为两条路径最终都要到最右端),我们可以理解$d(n,j)=dist(j,n)$,和上面的状态方程结合起来,可以得到$d(n-1,j)=dist(n-1,n)+dist(j,n)$(刘汝佳)(我觉得还是分开来看来处理边界条件比较方便)。起始的时候,因为规定了$i>j$,所以只能写$$d(2,1)$,然后加上1走到2的距离就是总距离了。

    代码如下:

     1 //
     2 //  main.cpp
     3 //  Tour
     4 //
     5 //  Created by Yanbin GONG on 12/3/2018.
     6 //  Copyright © 2018 Yanbin GONG. All rights reserved.
     7 //
     8 
     9 #include <iostream>
    10 #include <stdio.h>
    11 #include <string>
    12 #include <string.h>
    13 #include <algorithm>
    14 #include <cmath>
    15 
    16 using namespace std;
    17 
    18 struct coord{
    19     int x,y;
    20 };
    21 
    22 int n;//number of points
    23 coord nodes[105]; //假设最多100个点,UVa官网貌似没给大小
    24 double d[105][105];
    25 bool visited[105][105];
    26 double ans;
    27 
    28 
    29 double dis(int a, int b){
    30     return sqrt((nodes[a].x-nodes[b].x)*(nodes[a].x-nodes[b].x)+(nodes[a].y-nodes[b].y)*(nodes[a].y-nodes[b].y));
    31 }
    32 
    33 double dp(int a, int b){
    34     if(visited[a][b]==true){
    35         return d[a][b];
    36     }
    37     visited[a][b] = true;
    38     if(a==n){
    39         d[a][b] = dis(b,n);
    40         return d[a][b];//终点条件
    41     }
    42     d[a][b] = min(dp(a+1,b)+dis(a,a+1),dp(a+1,a)+dis(b,a+1));
    43     return d[a][b];
    44 }
    45 
    46 int main(){
    47     //原题用freopen,读取文件
    48     while(scanf("%d",&n)!=EOF){
    49         memset(d,0x3f,sizeof(d));
    50         memset(visited,0,sizeof(visited));
    51         for(int i=1;i<=n;i++){
    52             cin>>nodes[i].x>>nodes[i].y;
    53         }
    54         dp(2,1);
    55         ans = d[2][1] + dis(1,2);
    56         printf("%.2lf
    ",ans);
    57     }
    58     
    59     return 0;
    60 }
    View Code

     相同问题:OJ 440

  • 相关阅读:
    032 Gradle 下载的依赖jar包在哪?
    031 can't rename root module,Android Studio修改项目名称
    030 Cannot resolve symbol'R' 问题解决汇总大全
    029 Android Studio层级显示目录文件
    028 You are about to commit CRLF line separators to the Git repository.It is recommended to set the core. autocrlf Git attribute to true to avoid line separator issues If you choose Fix and Comit ,
    027 【Android基础知识】Android Studio 编译慢及 Adb connection Error:远程主机强迫关闭了一个现有的连接
    026 Android Studio 和Gradle版版本对应关系
    025 Cause: org.jetbrains.plugins.gradle.tooling.util.ModuleComponentIdentifierIm
    024 Android Studio上传项目到Github 最全记录
    023 解决AndroidStudio下载gradle慢的问题
  • 原文地址:https://www.cnblogs.com/cmbyn/p/8548651.html
Copyright © 2011-2022 走看看