lanqiao OJ 1032 画廊

本文介绍了如何使用C++编程解决在给定画廊空间中,从起点到终点的最短路径问题,通过动态规划计算左右两侧画廊之间的最短距离并求解最终距离。
摘要由CSDN通过智能技术生成

1.画廊 - 蓝桥云课 (lanqiao.cn)

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std ;
typedef long long LL ;
struct edge{
    double x , y ;
};//定义点 , 把每一个位置换成坐标 方便计算距离 
const int N = 510 ;
int L , R ;
edge l[N] ,r[N] ;//记录左右两边每一个的距离 
double d, w ;
double f[N][N][2] ;//开三维数组,表示左边整理了i副右边整理了j副切最后一个落点再左边或者右边的最短距离 
double dd(edge a, edge b) {
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y)) ;
}//用于计算距离 
int main(){
    cin >> L >> R >> d >> w ;
    for(int i = 1  ; i <= L ; i ++){
        l[i].x = 0 ;cin >> l[i].y ;//画廊左侧 
    } 
    for(int j = 1 ;  j <= R ; j ++) {
        r[j].x = w ;cin >> r[j].y ;//画廊右侧 
    }
    edge a ; a.x = w/2 ; a.y = 0 ;//定义起点,即画廊起点中央位置 
    edge b ; b.x = w/2 ; b.y = d ;//定义终点,即画廊终点中央位置 
    memset(f,127 , sizeof f) ;//要取最小值先初始化数组 //关于memset初始化double注意一下
    f[1][0][0] = dd(l[1] , a) ;//起点跳到第一个左边画廊的距离 
    f[0][1][1] = dd(r[1] , a) ;//起点跳到第一个右边画廊的距离 
    for(int i = 0  ; i <= L ; i ++){//必须从第一个数开因为可以一直跳画廊左边 
        for(int j = 0 ; j <= R ; j ++){//必须从第一个数开因为可以一直跳画廊右边 
            //1.f[i][j][0/1] 要参与判断的原因是当i=1,j=0时f[1][0][0]就变值了
			//2.f[i-1][j][0] 一共就两种变化的情况 要不然从同行来 ,要不然从对侧来 
			if(i) f[i][j][0] = min( f[i][j][0],min(f[i-1][j][0] + dd(l[i-1] , l[i] ) ,f[i-1][j][1] + dd(l[i],r[j]) )); 
            if(j) f[i][j][1] = min( f[i][j][1],min(f[i][j-1][1] + dd(r[j-1] , r[j] ) ,f[i][j-1][0] + dd(l[i],r[j]) )); 
        }
    }
    double ans = 0 ;
    //最后落点落在最后两侧的最小值加上到终点的距离就是最终距离 
    ans = min(f[L][R][0] + dd(l[L] , b) , f[L][R][1] + dd(r[R] , b)) ;

    printf("%.2lf",ans) ;
    return 0 ;
}

注意一下memset对double的使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值