【BZOJ5471】[FJOI2018]邮递员问题(动态规划)
【BZOJ5471】[FJOI2018]邮递员问题(动态规划)
题面
给定平面上若干个点,保证这些点在两条平行线上,给定起点终点,求从起点出发,遍历所有点后到达终点的最短路径长度。
题解
不会做,于是点开LOJ,点开除了\(std\)之外唯一过的人的代码,照着打了一遍QwQ......
然后再对着代码YY一遍就有了这篇东西。。。。。。
强制令起点的位置是第\(0\)行(方便而已)。
在第\(0\)行枚举一个\(i\),在第一行枚举一个\(j\)。
设\(f[j][0]\)表示第\(1\)行\([j+1,n_1]\)这些点已经走完,第\(0\)行\([i,n_0]\)已经走完,然后到达终点的最短路。
设\(f[j][1]\)表示第\(1\)行\([j,n_1]\)已经走完,第\(0\)行\([i+1,n_0]\)已经走完,然后达到终点的最短路。
把\(i\)按照从前往后或者从后往前的顺序枚举,到达起点就直接更新答案。
因为从起点出发可以向两个方向走,所以前后都要做一遍\(dp\)。
转移的话就是一堆讨论。
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAX 10100
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n[2],ty[2],pos[2];
double h,tx[2],x[2][MAX],f[MAX][2];
double Dis(int i,int j)
{
double d=fabs(x[0][i]-x[1][j]);
return sqrt(d*d+h*h);
}
double ToEnd(int i,int j)
{
double d=fabs(x[i][j]-tx[1]);
return i==ty[1]?d:sqrt(h*h+d*d);
}
double Calc()
{
double ret=1e18;
sort(&x[0][1],&x[0][n[0]+1]);
sort(&x[1][1],&x[1][n[1]+1]);
for(int i=n[0];i;--i)
{
if(i==n[0])
for(int j=n[1];j;--j)
{
f[j][0]=j==n[1]?ToEnd(0,n[0]):min(f[j+1][1]+Dis(n[0],j+1),Dis(n[0],n[1])+x[1][n[1]]-x[1][j+1]+ToEnd(1,j+1));
f[j][1]=j==n[1]?ToEnd(1,n[1]):f[j+1][1]+x[1][j+1]-x[1][j];
}
else
for(int j=n[1];j;--j)
if(j==n[1])
{
f[j][1]=min(f[j][0]+Dis(i+1,j),Dis(n[0],n[1])+x[0][n[0]]-x[0][i+1]+ToEnd(0,i+1));
f[j][0]+=x[0][i+1]-x[0][i];
}
else
{
f[j][1]=min(f[j][0]+Dis(i+1,j),f[j+1][1]+x[1][j+1]-x[1][j]);
f[j][0]=min(f[j][0]+x[0][i+1]-x[0][i],f[j+1][1]+Dis(i,j+1));
}
ret=min(ret,x[0][i]-x[0][1]+tx[0]-x[0][1]+Dis(i,1)+f[1][1]);
ret=min(ret,fabs(x[0][i]-tx[0])+x[0][i]-x[0][1]+Dis(1,1)+f[1][1]);
if(x[0][i]<=tx[0])
{
ret=min(ret,tx[0]-x[0][1]+Dis(1,1)+f[1][1]);
break;
}
}
return ret;
}
int main()
{
scanf("%d%d%d%d%d%d%lf",&n[0],&n[1],&ty[0],&pos[0],&ty[1],&pos[1],&h);
int r=0;if(ty[0])r=1,swap(n[0],n[1]),ty[0]^=1,ty[1]^=1;
for(int t=0;t<=1;++t)
for(int i=1;i<=n[t^r];++i)
scanf("%lf",&x[t^r][i]);
tx[0]=x[ty[0]][pos[0]];
tx[1]=x[ty[1]][pos[1]];
double ans=Calc();
for(int t=0;t<=1;++t)
for(int i=1;i<=n[t];++i)
x[t][i]=20000-x[t][i];
tx[0]=20000-tx[0];tx[1]=20000-tx[1];
ans=min(ans,Calc());
printf("%.2lf\n",ans);
return 0;
}
【BZOJ5471】[FJOI2018]邮递员问题(动态规划)的更多相关文章
- LOJ2522:[FJOI2018]邮递员问题(乱搞)
传送门 乱搞. 可以发现如果起点在左边界,终点在右边界的时候上下走的点一定是连续的(可能吧) 那么可以设 \(f_{i,j,0/1}\) 表示当前上面到 \(i\),下面到 \(j\),当前在上面/下 ...
- yyb省选前的一些计划
突然意识到有一些题目的计划,才可以减少大量查水表或者找题目的时间. 所以我决定这样子处理. 按照这个链接慢慢做. 当然不可能只做省选题了. 需要适时候夹杂一些其他的题目. 比如\(agc/arc/cf ...
- 【BZOJ5469】[FJOI2018]领导集团问题(动态规划,线段树合并)
[BZOJ5469][FJOI2018]领导集团问题(动态规划,线段树合并) 题面 BZOJ 洛谷 题解 题目就是让你在树上找一个最大的点集,使得两个点如果存在祖先关系,那么就要满足祖先的权值要小于等 ...
- 增强学习(三)----- MDP的动态规划解法
上一篇我们已经说到了,增强学习的目的就是求解马尔可夫决策过程(MDP)的最优策略,使其在任意初始状态下,都能获得最大的Vπ值.(本文不考虑非马尔可夫环境和不完全可观测马尔可夫决策过程(POMDP)中的 ...
- 简单动态规划-LeetCode198
题目:House Robber You are a professional robber planning to rob houses along a street. Each house has ...
- 动态规划 Dynamic Programming
March 26, 2013 作者:Hawstein 出处:http://hawstein.com/posts/dp-novice-to-advanced.html 声明:本文采用以下协议进行授权: ...
- 动态规划之最长公共子序列(LCS)
转自:http://segmentfault.com/blog/exploring/ LCS 问题描述 定义: 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则 ...
- C#动态规划查找两个字符串最大子串
//动态规划查找两个字符串最大子串 public static string lcs(string word1, string word2) { ...
- C#递归、动态规划计算斐波那契数列
//递归 public static long recurFib(int num) { if (num < 2) ...
随机推荐
- 如何优化Docker储存
大家在使用Docker的过程中,有没有想过,Docker在本地存储镜像时把文件存储在哪里了呢?有没有对文件的总大小做一定的限制呢?能不能调整本地存储的位置及总限制大小呢?今天,我们就从这些问题入手,来 ...
- Git远程分支的回退
下午发现上午提交的一个版本有问题,在回退本地分支后,发现还必须要回退远程分支的版本.网上查找到的资料如下: #新建old_master分支做备份 git branch old_master #push ...
- form-data、x-www-form-urlencoded的区别
form-data可以上传文件格式的,比如mp3.jpg这些:x-www-form-urlencoded不能选择格式文件,只能传key-value这种string格式的内容.
- 【学习总结】C-翁恺老师-入门-第0周<程序设计与C>
[学习总结]C-翁恺老师-入门-总 1-首先按视频说的下载编辑器 <DevC++> 并一路默认设置: 安装包下载链接 (我有vc6.0不过预感告诉我老师要用类似CS50里那种命令行编辑器? ...
- 使用jmeter来发送json/gzip格式数据 --------笔记
一.使用jmeter来发送gzip数据 有时候我们需要模拟在客户端将数据压缩后, 发送(post)到服务器端. 通常这种情况,会发生在移动终端上. 这样做的好处, 是可以节省流量. 当然, 服务器返 ...
- windows中dir命令
最近想用dos命令打印指定目录下的所有文件夹的完整路径.最终发现可用dir命令来实现.在此学习下dir的各项命令. 32位win7系统上,打印帮助文档. D:\test>dir /? 显示目录中 ...
- css3新属性box-orient
前言 box-orient属性经常与display:box属性结合使用 div { width:350px; height:100px; border:1px solid black; /* Fire ...
- Oracle分析函数row_number()等的使用实例
--分析函数 --rank() over(order by) --值相同,排名相同,序号跳跃 select * from t_account select rank() over(order by u ...
- Codeforces 1154C Gourmet Cat
题目链接:http://codeforces.com/problemset/problem/1154/C 题目大意: 主人有一只猫.周一&周四&周日:吃鱼周二&周六:吃兔子周三 ...
- Window下通过SecureCRT的SSH2跳转到另一台Linux服务器
我工作中的示例: 先登录192.168.2.145 Your password will be expired in 200 days.Welcome to Baoleiji System.Last ...