【题解】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题(最后还是在题解的帮助下冥思苦想才过掉的题),窝觉得此题肥肠之脑洞,写此博客纪念 题解 过河 先来日常手玩样例: 咦感觉怎么手玩答案都像是 ...
随机推荐
- protobuf安装流程
protobuf安装流程 环境 平台 Ubuntu16.04 依赖 autoconf automake libtool curl make g++ 安装流程 在Ubuntu / Debian上,您 ...
- mitmdump+python的使用(代码篇)
mitmproxy+python代码篇 一.上个推文我们介绍了mitmdump的简单操作,下面我们开始学习,mitmdump配合python脚本的使用.第一点先讲日志输出.请看图片 先导入ctx模块: ...
- Jenkins登录无效
解决办法: 进入Jenkins安装目录: 1:进入D:\jenkins\users\admin 这个目录下找到config.xml 可以看到里面的用户名是admin 2:进入D:\jenkins\s ...
- 重学 Java 设计模式:实战代理模式「模拟mybatis-spring中定义DAO接口,使用代理类方式操作数据库原理实现场景」
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 难以跨越的瓶颈期,把你拿捏滴死死的! 编程开发学习过程中遇到的瓶颈期,往往是由于看不 ...
- .Net Core服务监控报警指标上报Prometheus+Grafana
前言 简单集成Prometheus+Grafana,指标的上报收集可视化. Prometheus Prometheus是一个监控平台,监控从HTTP端口收集受监控目标的指标.在微服务的架构里Prome ...
- Python数据处理常用工具(pandas)
目录 数据清洗的常用工具--Pandas 数据清洗的常用工具 Pandas常用数据结构series和方法 Pandas常用数据结构dataframe和方法 常用方法 数据清洗的常用工具--Pandas ...
- 数据库事务(2)---ACID与并发问题
事务 事务(Transaction),一般是指要做的或所做的事情.在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit).在计算机术语中,事务通常就是指数据库事务. 概念 一 ...
- mysql 出现You can't specify target table for update in FROM clause错误的解决方法
mysql出现You can’t specify target table for update in FROM clause 这个错误的意思是不能在同一个sql语句中,先select同一个表的某些值 ...
- 使用迭代器模式批量获得数据(C#实现)
先说一下项目的背景,以前曾经做过一个项目,根据Excel中的数据批量的到网页上抓取数据,将抓取到的数据批量的回填到Excel中.这个Excel中有很多行的记录(多的时候会有好几千行),每一行数据存储能 ...
- 入门大数据---Spark_Streaming整合Flume
一.简介 Apache Flume 是一个分布式,高可用的数据收集系统,可以从不同的数据源收集数据,经过聚合后发送到分布式计算框架或者存储系统中.Spark Straming 提供了以下两种方式用于 ...