回收可乐瓶(dp)

E-回收可乐瓶_2022河南萌新联赛第(六)场:郑州大学 (nowcoder.com)

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

题目描述

小A和小Q负责回收校园内的可乐瓶,校园可以看做是一个二维平面,每一个位置都可以用一个坐标表示。某一时刻校园内可能会丢弃一个可乐瓶,小A和小Q看到后会立即走到可乐瓶所在位置将它捡起,再走到垃圾箱的位置,将可乐瓶丢到垃圾箱中。对于每个被丢弃的可乐瓶,小A和小Q至少有一个人去捡并丢进垃圾箱。每次扔完可乐瓶后小A或小Q会停留在垃圾箱的位置,直到去捡下一个瓶子。现在给你小A、小Q以及垃圾箱的位置,再按时间顺序给出每个被丢弃的可乐瓶的位置,每一时刻最多会出现一个可乐瓶,请你合理安排小A和小Q捡瓶子的次序,使得两人走的距离之和最小,要求一个瓶子丢到垃圾箱后才能捡下一个瓶子,并输出这个最小距离之和。

当然,允许小A或者小Q一个人拣完全部的可乐瓶,假如这样走的距离最小的话可以做出这样的安排。

输入描述:

第一行六个整数a_x,a_y,b_x,b_y,c_x,c_y,小A舒适位置(a_x,a_y),小Q初始位置(b_x,b_y),垃圾桶位置(c_x,c_y)。

第二行一个正整数n(1⩽n⩽200000),表示可乐瓶的个数。

接下来n行,每行两个整数(x,y)(0⩽∣x∣,∣y∣⩽1000),表示可乐瓶的位置。

输出描述:

输出距离之和的最小值,保留两位小数。

输入

1 1 0 0 3 2
3
1 2
0 1
3 3

输出

9.16

分析:

一,小红(a)和小明(b)位置只可能有两个

           1,捡了垃圾,就会去丢垃圾,位置此后保存在垃圾桶位置(t)

            2,没有捡垃圾,位置保持不变,在原位置

二,dp所有状态只有4种

        dp[n][0][0] 捡第n件垃圾时,小红和小明都没有捡过垃圾

        dp[n][1][0]捡第n件垃圾时,小红捡过垃圾,小明没有捡过垃圾

        dp[n][0][1]捡第n件垃圾时,小红没有捡过垃圾,小明捡过垃圾

        dp[n][1][1]捡第n件垃圾时,小红和小明都捡过垃圾

三,由以上分析可知,dp方程

        a:小红位置  b:小明位置  t:垃圾桶位置  h:垃圾位置

        dis0=dis(a,h)+dis(h,t)

        dis1=dis(b,h)+dis(h,t)

        dis2=dis(h,t)*2

        dp[n][1][0]=min(dp[n-1][0][0]+dis0,dis[n-1][1][0]+dis2)

        dp[n][0][1]=min(dp[n-1][0][1]+dis1,dis[n-1][0][1]+dis2)

        dp[n][1][1]=min({dp[n-1][1][1]+dis2,

                                 dis[n-1][1][0]+dis1,

                                 dis[n-1][0][1]+dis0})

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+6;
struct node{
	double x,y;
};
node a,b,t,h;
double dp[maxn][2][2];
double dis(node a,node b){
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int main(){
	cin>>a.x>>a.y>>b.x>>b.y>>t.x>>t.y;
	int n;
	cin>>n;
	memset(dp,0x7f,sizeof(dp));
	dp[0][0][0]=0;
	for(int i=1;i<=n;i++){
		cin>>h.x>>h.y;
		
		dp[i][1][0]=min((dp[i-1][0][0]+dis(a,h)+dis(h,t)),
						 dp[i-1][1][0]+dis(t,h)*2);
		dp[i][0][1]=min((dp[i-1][0][0]+dis(b,h)+dis(h,t)),
						 dp[i-1][0][1]+dis(t,h)*2);
		dp[i][1][1]=min({dp[i-1][0][1]+dis(a,h)+dis(h,t),
						 dp[i-1][1][0]+dis(b,h)+dis(h,t),
						 dp[i-1][1][1]+dis(t,h)*2});
		
	}
	
	printf("%.2lf",min({dp[n][1][0],dp[n][0][1],dp[n][1][1]}));
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值