【题解】p1809 过河问题
题目分析
现有n个人在东岸,要过河去西岸。开始东岸有一艘船,船最多可承载2人,过河时间以耗时最长的人所需时间为准。
给定n个人的过河时间a,求所有人从东岸到西岸所需的最短时间。
当\(n=2\)时,易得答案为\(a[2]\)。但问题在于当\(n>2\)如何解决。
贪心分析
对所有数据从小到大排序。
从小规模数据出发,当\(n=3\)时,不难想到可以先用\(a[1]\)将\(a[3]\)送过去,再让\(a[1]\)回来,这样就回归了\(n=2\)的情况。
\(n>3\)时情况略为复杂,我们考虑推导问题的几个简单性质。
对于每次船在西岸时,如果需要某个人将船送回来,则优先让西岸a最小的\(dalao\)回来。
证明:假设西岸有过河时间\(a[1],a[2],a[3]\)的三个人,则让\(a[1]\)回来,必然导致东岸后续的子问题最优。
如此便得到一个简单的贪心,我们便无需考虑回来的情况,只需要思考如何将人送过去。
重要推论:在问题结束前,不甘寂寞的\(dalao\) \(a[1]\)不可能被留在西岸。也就是说,\(a[1]\)只要过去,就必然要将船送回来。
对于\(4<=i<=n\)的所有\(a[i-1]\),它到西岸只有两种可能方式:自己和\(a[1]\)过去,或者自己和\(a[i]\)过去。
对于第一种方式:就相当于\(a[i-1]\)自己过去,\(a[1]\)负责送船回来,代价\(a[i-1]+a[1]\)。
对于第二种方式:如果不希望\(a[i-1]\)被贡献到答案中,则只能选择一个\(j>i-1\)的小蒟蒻\(a[j]\)来当\(a[i-1]\)的拖油瓶。
但问题在于,过弱的蒟蒻\(a[j]\)不能和\(dalao\) \(a[i-1]\)玩,或者说\(dalao\) \(a[i-1]\)不能选择太弱的\(a[j]\)来当拖油瓶,否则代价会过大。因此\(a[i-1]\)只能选择\(a[i]\)来当它的拖油瓶。
那么两人过去以后,谁给他们送船回来呢?由于\(a[1]\)不可能在西岸等着他们,因此需要提前让\(a[1]\)带\(a[2]\)过去,留\(a[2]\)为他们送船。代价\(a[2]+a[1]+a[i]+a[2]\)。
由此,我们可以得到状态转移方程:$$f[i]=min(f[i-1]+a[i]+a[1],f[i-2]+a[2]+a[1]+a[i]+a[2])$$
几乎每一篇题解都提到了这个方程,那么问题来了,为什么\(f[i]\)由\(f[i-1]和f[i-2]\)中取一转移即可,而不能继续考虑到\(f[i-3]\)?
我们考虑已知\(f[i-3]\),然后新来了三个蒟蒻,对于\(a[i-2]\),他不可能会带\(a[i]\)过河,也就是要么自己走,要么带\(a[i-1]\)走。也就是说\(a[i-2]\)的决策与\(a[i]\)无关。
因此求\(f[i]\)时,只要考虑\(a[i-1]\)的决策即可,也就是从\(f[i-1]\)和\(f[i-2]\)两个状态中取一转移即可。
code:
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=100010;
int n,a[MAXN],f[MAXN];
int main()
{
// freopen("in.txt","r",stdin);
scanf("%d",&n);
for(int i=1;i<=n;++i)scanf("%d",a+i);
f[1]=a[1];
f[2]=a[2];
f[3]=a[3]+a[1]+a[2];
for(int i=4;i<=n;++i)f[i]=min(f[i-1]+a[i]+a[1],f[i-2]+a[2]+a[1]+a[i]+a[2]);
printf("%d\n",f[n]);
return 0;
}
【题解】p1809 过河问题的更多相关文章
- 贪心—— P1809 过河问题_NOI导刊2011提高(01)
洛谷——P1809 过河问题_NOI导刊2011提高(01) 题目描述 有一个大晴天,Oliver与同学们一共N人出游,他们走到一条河的东岸边,想要过河到西岸.而东岸边有一条小船. 船太小了,一次只能 ...
- 洛谷 P1809 过河问题 题解
题面 这道题是一道贪心+DP的好题: 首先排序是一定要干的事情. 然后我们分情况处理: 1.如果剩一个人,让最小的回来接他 2.如果剩两个人,让最小的回来接,剩下的那两个人(即最大的两个人)过去,让次 ...
- 【P1809 过河问题】题解
贪心,我们设时间序列为 \(\{a_i\}\),长度为 \(n\)(先排序 \(\{a_i\}\)). 分类讨论(其中的「\(1\)」「\(2\)」等均指「速度第 \(1\) 人」「速度第 \(2\) ...
- 洛谷P1809 过河问题 经典贪心问题
作者:zifeiy 标签:贪心 题目链接:https://www.luogu.org/problem/P1809 我们假设第 \(i\) 个人过河的耗时是 \(t[i]\) ,并且 \(t[i]\) ...
- 洛谷P1809 过河问题_NOI导刊2011提高(01)
To 洛谷.1809 过河问题 题目描述 有一个大晴天,Oliver与同学们一共N人出游,他们走到一条河的东岸边,想要过河到西岸.而东岸边有一条小船. 船太小了,一次只能乘坐两人.每个人都有一个渡河时 ...
- luogu P1809 过河问题_NOI导刊2011提高(01)
题目描述 有一个大晴天,Oliver与同学们一共N人出游,他们走到一条河的东岸边,想要过河到西岸.而东岸边有一条小船. 船太小了,一次只能乘坐两人.每个人都有一个渡河时间T,船划到对岸的时间等于船上渡 ...
- P1809 过河问题_NOI导刊2011提高(01)
题目描述 有一个大晴天,Oliver与同学们一共N人出游,他们走到一条河的东岸边,想要过河到西岸.而东岸边有一条小船. 船太小了,一次只能乘坐两人.每个人都有一个渡河时间T,船划到对岸的时间等于船上渡 ...
- [Codeforces]#179 div1-----295ABCDE
摘自我的github:https://github.com/Anoxxx The Solution Source: Codeforces Round #179 (Div. 1) VJudge链接: h ...
- luoguP1502过河题解
日常吐(fei)嘈(hua) 这道题作为最近卡了我3天的dp题(最后还是在题解的帮助下冥思苦想才过掉的题),窝觉得此题肥肠之脑洞,写此博客纪念 题解 过河 先来日常手玩样例: 咦感觉怎么手玩答案都像是 ...
随机推荐
- Python实现海贼王的歌词组成词云图
前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:一粒米饭 喜欢的朋友欢迎关注小编,除了分享技术文章之外还有很多福利, ...
- php使用json_encode中遇见问题?
注:php版本5.4下,不支持json_encode对中文的处理,要么升级php版本. json_encode($value,$options) 其中有2个比较常用到的参数: 1.JSON_UNESC ...
- EIGRP-14-EIGRP的命名模式
从IOS 15.0(1)M版本开始,工程师可以在路由器上使用命名模式(Named Mode)配置EIGRP进程.按照IPv4和IPv6,通过AS号来配置EIGRP进程的做法称为经典模式(Classic ...
- 容器技术之Docker资源限制
上一篇我们聊到了docker容器的单机编排工具docker-compose的简单使用,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13121678.html: ...
- Docker数据管理与挂载管理
介绍如何在 Docker 内部以及容器之间管理数据:在容器中管理数据主要有两种方式:数据卷(Volumes).挂载主机目录 (Bind mounts) 镜像来源 [root@docker01 ~]# ...
- 使用addEventListener绑定事件是关于this和event记录
DOM元素使用addEventListener绑定事件的时候经常会碰到想把当前作用域传到函数内部,可以使用以下两种放下: var bindAsEventListener=function (objec ...
- 记录工作中遇到的BUG,经典的数据库时区问题和字段类型tinyint(1)问题
记录工作中发现的相对而言经典的问题 [数据库时区问题] 我个人数据库配置为CST 如下 我们测试环境的数据库配置为UTC 如下 倘若我修改了测试环境数据库时区为CST.由此造成的问题是 系统读取到数据 ...
- 「从零单排canal 03」 canal源码分析大纲
在前面两篇中,我们从基本概念理解了canal是一个什么项目,能应用于什么场景,然后通过一个demo体验,有了基本的体感和认识. 从这一篇开始,我们将从源码入手,深入学习canal的实现方式.了解can ...
- 7-4 是否同一棵二叉搜索树 (25分) JAVA
给定一个插入序列就可以唯一确定一棵二叉搜索树.然而,一棵给定的二叉搜索树却可以由多种不同的插入序列得到. 例如分别按照序列{2, 1, 3}和{2, 3, 1}插入初始为空的二叉搜索树,都得到一样的结 ...
- Python3-shutil模块-高级文件操作
Python3中的shutil模块提供了对文件和容器文件的一些高级操作 shutil.copy(src, dst) 拷贝文件,src和dst为路径的字符串表示,copy()会复制文件数据和文件权限,但 ...