【题解】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题(最后还是在题解的帮助下冥思苦想才过掉的题),窝觉得此题肥肠之脑洞,写此博客纪念 题解 过河 先来日常手玩样例: 咦感觉怎么手玩答案都像是 ...
随机推荐
- 你真的了解EF吗?关于EntityFramework的高级优化
接上一篇文章.现在写程序,做项目不是说功能做完就完事了,在平常的开发过程中对于性能的考虑也是极其重要的. 关于ef的那些事,今天就来说说吧.首先必须得知道.net ef在程序中的五种状态变化过程与原理 ...
- numpy.random.randn()与numpy.random.rand()的区别
numpy中有一些常用的用来产生随机数的函数,randn()和rand()就属于这其中. numpy.random.randn(d0, d1, …, dn)是从标准正态分布中返回一个或多个样本值. n ...
- Vue —— VueX精讲(1)
大纲 这一讲我们最主要的就是学习vue中的数据管理VueX,这个是一个大杀器 一.回顾一些Promise相关的东西 Promise 有几个比较重要的方法,最重要的还是有一个叫做all的方法,这个也是非 ...
- uni-app热更新
开发工具HbuilderX开发框架 uni-app.h5+1.生成 App 资源升级包1.1.修改版本号1.2.首先,更新 manifest.json 中的版本号.比如之前是 1.0.0,那么新版本应 ...
- CAT12提取surface指标
介绍 基于表面的形态学分析(VSM)的方法被越来越多的研究者使用.本文主要介绍基于SPM12和CAT12工具包进行ROI-based VSM的处理步骤. 方法 本文数据处理使用的工具是MATLAB,S ...
- 关于Attach *.mdf数据库联想到的备份
要求: 将SQL2008R2的*.mdf ( 当时内部版本不详,此时无挂接在MSSQL服务器上的数据库,只有*.mdf文件 ) --->>> SQL2008R2中,附加到现有SQL2 ...
- Scrum Master教你四招,瓦解团队内部刺头
摘要:<Scrum精髓>一书中将Scrum Master的职责总结为六类:敏捷教练,服务型领导,“保护伞”,“清道夫”,过程权威,“变革代言人”.作为“保护伞“,Scrum Master应 ...
- (一)Log4j使用
原文链接:https://www.jianshu.com/p/eb4ac2571c94?tdsourcetag=s_pctim_aiomsg 1.先创建个maven项目,在我们项目的pom文件中导入l ...
- C# 泛型的基本知识,以及什么是泛型?
1.1 泛型概述 1.1.1 泛型广泛用于容器(collections) 1.1.2 命名空间System.Collections.Generic 1.2 泛型的优点. 以前类型的泛化(general ...
- Charles 功能详解
Charles的功能有? 1 抓取http和https 网络封包(抓包) 2 Charles 的断点请求 通过断点修改参数 在指定接口打上断点 右键点击接口选择 breakpoints 然后 导航栏 ...