P4823 [TJOI2013] 拯救小矮人
感觉这个题的操作很新奇,做个记录。
大概题面:
一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决
定搭一个人梯。即:一个小矮人站在另一小矮人的肩膀上,直到最顶端
的小矮人伸直胳膊可以碰到陷阱口。
对于每一个小矮人,我们知道他从脚到肩膀的高度 \(A_i\),并且他的胳膊长
度为 \(B_i\)。陷阱深度为 \(H\)。
如果我们利用矮人 \(1\),矮人 \(2\),矮人 \(3\),\(\ldots\),矮人 \(k\) 搭一个梯子,满足
\(A_1 + A_2 + A_3 + \ldots + A_k + B_k \geq H\),那么矮人 \(k\) 就可以离开陷阱逃跑了,
一旦一个矮人逃跑了,他就不能再搭人梯了。
我们希望尽可能多的小矮人逃跑,问最多可以使多少个小矮人逃跑。
数据范围:\(1 \leq N\leq 2000\),\(1 \leq A_i,B_i,H\leq10^5\)。
1:贪心+dp
首先小矮人出去一定与顺序有关,前一个小矮人出去可能导致后面小矮人无法出去。
那么从贪心的角度思考,将小矮人按 \(a_i+b_i\) 从小到大排序,
可以对比,当 \(a_i+b_i < a_j+b_j\) 时,\(H+a_i+b_i\) 与 \(H+a_j+b_j\) 那个更优? (*交换对比)
发现当 \(a_i+b_i\) 先出去时,其他小矮人更有机会出去,而 \(a_j+b_j\) 先出去时,其他小矮人可能够不到而无法出去。
当 \(a_i+b_i = a_j+b_j\) 时,显然 \(a_i\) 较大的人应该留下(让人梯更长)。
我们发现 \(N\) 较小,可以枚举考虑到每个人的状态,考虑dp。
接下来考虑如何dp。很自然的想到有 \(f_{i,j}=x\) 为枚举第 \(i\) 个小矮人时,人梯长度为 \(j\) 时,最多能逃出 \(x\) 个人。 (我好菜...)
发现 \(j\) 很大,不好转移。所以交换一下,改成:
\(f_{i,j}=x\) 为枚举第 \(i\) 个小矮人时,能逃出 \(j\) 个人时,人梯长度最大为 \(x\) 。 (*枚举信息交换)
考虑转移,当有 \(f_{i-1,j-1}+b_i \geq H\) 时,小矮人 \(i\) 可以逃出。
则此时有 \(f_{i,j}=max(f_{i,j},f_{i-1,j-1}-a_i)\)
我们发现 \(f_{i,j}\) 在转移时只与上一位 \(i-1\) 有关,所以考虑滚动数组将 \(i\) 这一维优化掉。 (*滚动数组)
则:\(f_j=max(f_j , f_{j-1}-a_i)\)
Code:
#include<bits/stdc++.h>
using namespace std;
const int N=2005;
int n,h;
struct node{
int x,y;
bool operator<(const node& p)const{
if(x+y==p.x+p.y)return x<p.x;
else return x+y<p.x+p.y;
}
}a[N];
int f[N];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);
sort(a+1,a+1+n);
scanf("%d",&h);
memset(f,-0x3f,sizeof(f));
f[0]=0;
for(int i=1;i<=n;i++)f[0]+=a[i].x;
for(int i=1;i<=n;i++){
for(int j=n;j>=1;j--){
if(f[j-1]+a[i].y>=h){
f[j]=max(f[j],f[j-1]-a[i].x);
}
}
}
for(int i=n;i>=0;i--){
if(f[i]>=0){
printf("%d\n",i);
break;
}
}
return 0;
}
这个题目也可以用反悔贪心,(有时间就写在别的地方,补链接)
2:我学会了:
- 考虑顺序。并且可以通过交换在对比知道谁应该在前面。
- 有时不好枚举时可以交换信息
P4823 [TJOI2013] 拯救小矮人的更多相关文章
- [luogu] P4823 [TJOI2013]拯救小矮人(贪心)
P4823 [TJOI2013]拯救小矮人 题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以 ...
- [洛谷P4823] TJOI2013 拯救小矮人
问题描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口. 对于每一个小矮人,我们知道他从 ...
- Luogu P4823 [TJOI2013]拯救小矮人
题目 \(n^2\)的dp已经成为辣鸡做法了,%%%wch. 首先一个结论:\(a+b\)小的人在上. 这个东西我们有三种方法解决证明: 1.感性理解,\(a+b\)越大的人逃生能力越强,放在下面就越 ...
- 贪心+DP【洛谷P4823】 [TJOI2013]拯救小矮人
P4823 [TJOI2013]拯救小矮人 题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以 ...
- BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP
BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀 ...
- 【BZOJ3174】[TJOI2013]拯救小矮人(贪心,动态规划)
[BZOJ3174][TJOI2013]拯救小矮人(贪心,动态规划) 题面 BZOJ 洛谷 题解 我们定义一个小矮人的\(A_i+B_i\)为它的逃跑能力. 我们发现,如果有两个小矮人\(x,y\), ...
- BZOJ3174 Tjoi2013 拯救小矮人(贪心+DP)
传送门 Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个 ...
- bzoj3174 [Tjoi2013]拯救小矮人
Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人, ...
- bzoj 3174: [Tjoi2013]拯救小矮人
Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人, ...
- [TJOI2013]拯救小矮人[排序+dp]
题意 题目链接 分析 Imagine的完美回答 重点大概是证明我们选出要救的小矮人一定可以根据 \(a_i+b_i\) 的大小进行排序救出. 注意这里关注的对象是可以保留的高度,所以我们的dp值才会表 ...
随机推荐
- 基于LoRA的RLHF
参考Github 开源模型LLM-Tuning 一.简介 (1)RLHF (基于人类反馈的强化学习) 分为三步: SFT (Supervised Fine-Tuning): 有监督的微调,使用正常的 ...
- Golang channel底层是如何实现的?(深度好文)
Hi 你好,我是k哥.大厂搬砖6年的后端程序员. 我们知道,Go语言为了方便使用者,提供了简单.安全的协程数据同步和通信机制,channel.那我们知道channel底层是如何实现的吗?今天k哥就来聊 ...
- Yaml配置文件语法详解
YAML 简介 YAML,即 "YAML Ain't a Markup Language"(YAML 不是一种标记语言)的递归缩写,YAML 意思其实是" Yet Ano ...
- 开启GitLab的邮件通知功能以及一些外观配置
前言 维护GitLab的同事离职了 刚好又有新实习生需要申请账号 只能我来出手了 其实之前安装了 GitLab 之后一直还是用得比较粗糙的 属于是勉强能用的水平,有些配置都还没改好 这次把邮件功能.域 ...
- oeasy教您玩转vim - 16 - # 行内贴靠
行头行尾 回忆上节课内容 跳跃 向前跳跃是 f 向后跳跃是 F 继续 保持方向是 ; 改变方向是 , 可以加上 [count] 来加速 还有什么好玩的吗? 动手 #这次还是用无配置的方式启动 vi - ...
- Docker 使用Docker创建MySQL容器
使用Docker创建MySQL容器 实践环境 Docker version 20.10.5 MySQL5.7 Centos 7.8 创建步骤 1.拉取MySQL镜像 docker pull mysql ...
- c++ 关于返回值、将亡值的调用研究
c++11引入右值引用,而出现右值引用的有这几种:返回值(将亡值),常量. class Obj { public: Obj() { cout << "构造函数" < ...
- ffmpeg精简
自:http://www.chinavideo.org/viewthread.php?tid=5567&extra=page%3D1&page=2 现在更新一下目前遇到的问题: 我想裁 ...
- .NET 轻量级 命令行工具 CSharpRepl
前言 当我们需要快速测试代码片段时,常见的做法是启动Visual Studio或使用在线代码编辑器.然而,Visual Studio的启动可能较为缓慢且占用较多系统资源,而在线编辑器则可能遇到语法支持 ...
- git操作之一:git add/commit/init
在日常的开发中,适用版本控制系统来进行协同开发已经是工作中的常态,使用比较多的要数git这个工具,今天就来说下git的日常用法以及在开发中的一些疑惑. 一.概述 git在日常开发中广泛应用,其概念可以 ...