题目链接

https://www.lydsy.com/JudgeOnline/problem.php?id=3174

题解

其实此题并不需要那么多YY的部分。

我们考虑若干个小矮人逃出的顺序。若跳出的 \(k\) 个小矮人依次为 \(p_1, p_2, \cdots , p_k\),那么我们一定可以将他们排序,使得对于任意的 \(i < j\) 满足 \(a_i + b_i < a_j + b_j\) 且按照该顺序依然能保证 \(k\) 个小矮人全部逃出。

证明如下:

若对于任意 \(i, j\),有 \(a_i + b_i < a_j + b_j\),且 \(j\) 比 \(i\) 先逃出,那么设 \(i\) 后面所有人的高度贡献为 \(s_1\),\(i\) 与 \(j\) 之间的人的高度贡献为 \(s_2\),\(h\) 为洞深,可得:

\[a_i + a_j +b_j \geq h - s_1 - s_2 \tag{1}$$ $$a_i + b_i \geq h - s_1 \tag{2}
\]

通过 \((2)\),我们可以推得:$$a_j + a_i + b_i \geq h - s_1 - s_2 \tag{3}$$

通过 \((2)\) 以及 \(a_i + b_i < a_j + b_j\),我们可以推得:$$a_j + b_j \geq h - s_1 \tag{4}$$

由 \((3), (4)\) 可以得出:\(i\) 比 \(j\) 先逃出依然是合法的。

这样,我们就证明了排序的正确性,那么就可以先排序再 dp 了。一个比较显然的状态是,我们设 \(f_{i, j}\) 表示考虑完排序后的前 \(i\) 个人,且已经逃走的人的 \(\sum a_k\) 的值为 \(j\) 时,最多能逃走多少人。不过由于 \(\sum a_k\) 可能很大,这样定义状态并不可行,因此我们需要把状态的第二维与状态本身的意义交换一下:设 \(f_{i, j}\) 表示考虑完排序后的前 \(i\) 个人,且已经逃走了 \(j\) 个人,这 \(j\) 个人的 \(\sum a_k\) 的最小值。这样,我们就能在 \(O(n^2)\) 的时间内完成这个 dp 了。

代码

#include<bits/stdc++.h>

using namespace std;

#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define debug(...) fprintf(stderr, __VA_ARGS__) typedef long long ll;
typedef long double ld;
typedef unsigned int uint;
typedef pair<int, int> pii;
typedef unsigned long long ull; template<typename T> inline void read(T& x) {
char c = getchar();
bool f = false;
for (x = 0; !isdigit(c); c = getchar()) {
if (c == '-') {
f = true;
}
}
for (; isdigit(c); c = getchar()) {
x = x * 10 + c - '0';
}
if (f) {
x = -x;
}
} template<typename T, typename... U> inline void read(T& x, U&... y) {
read(x), read(y...);
} template<typename T> inline bool checkMax(T& a, const T& b) {
return a < b ? a = b, true : false;
} template<typename T> inline bool checkMin(T& a, const T& b) {
return a > b ? a = b, true : false;
} const int N = 2e3 + 10, inf = 0x3f3f3f3f; struct State {
int x, y;
State () {}
State (int x, int y): x(x), y(y) {}
bool operator < (const State& a) const {
return x + y < a.x + a.y;
}
} s[N]; int n, f[N][N], h; int main() {
read(n);
int sa = 0;
for (register int i = 1; i <= n; ++i) {
read(s[i].x, s[i].y), sa += s[i].x;
}
sort(s + 1, s + 1 + n);
read(h);
memset(f, 0x3f, sizeof f);
f[0][0] = 0;
for (register int i = 1; i <= n; ++i) {
for (register int j = 0; j <= i; ++j) {
f[i][j] = f[i - 1][j];
}
for (register int j = 1; j <= i; ++j) {
if (sa - f[i - 1][j - 1] + s[i].y >= h) {
checkMin(f[i][j], f[i - 1][j - 1] + s[i].x);
}
}
}
int ans = 0;
for (register int i = 1; i <= n; ++i) {
if (f[n][i] < inf) {
ans = i;
}
}
printf("%d\n", ans);
return 0;
}

BZOJ3174. [TJOI2013]拯救小矮人(dp)的更多相关文章

  1. BZOJ3174:[TJOI2013]拯救小矮人(DP)

    Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人, ...

  2. BZOJ3174 Tjoi2013 拯救小矮人(贪心+DP)

    传送门 Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个 ...

  3. bzoj3174 [Tjoi2013]拯救小矮人

    Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人, ...

  4. BZOJ3174 TJOI2013 拯救小矮人 贪心、DP

    传送门 原问题等价于:先给\(n\)个人排好顺序.叠在一起,然后从顶往底能走即走,问最多能走多少人 注意到一个问题:如果存在两个人\(i,j\)满足\(a_i + b_i < a_j + b_j ...

  5. bzoj千题计划208:bzoj3174: [Tjoi2013]拯救小矮人

    http://www.lydsy.com/JudgeOnline/problem.php?id=3174 按a+b从小到大排序,a+b小的在上面,先考虑让它逃出去 正确性不会证 感性理解一下,最后一个 ...

  6. 【BZOJ-3174】拯救小矮人 贪心 + DP

    3174: [Tjoi2013]拯救小矮人 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 686  Solved: 357[Submit][Status ...

  7. BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP

    BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀 ...

  8. 【BZOJ3174】[TJOI2013]拯救小矮人(贪心,动态规划)

    [BZOJ3174][TJOI2013]拯救小矮人(贪心,动态规划) 题面 BZOJ 洛谷 题解 我们定义一个小矮人的\(A_i+B_i\)为它的逃跑能力. 我们发现,如果有两个小矮人\(x,y\), ...

  9. 贪心+DP【洛谷P4823】 [TJOI2013]拯救小矮人

    P4823 [TJOI2013]拯救小矮人 题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以 ...

随机推荐

  1. 【bootstrap】.container与.container_fluid

    .container与.container_fluid是bootstrap中的两种不同类型的外层容器,区别是: .container 类用于固定宽度并支持响应式布局的容器.不用你自己设宽度,通过< ...

  2. 2、Android-UI(RecyclerView)

    2.6.滚动控件-RecylerView ListView虽然使用的效果很好但是也是有缺点的 不使用一些技巧来提升它的运行效率,性能就非常差 扩展性也不是很好 只能实现数据的纵向滚动效果 实现横向滚动 ...

  3. Centos7 KDE 桌面Konsole 光标错位解决方法

    在使用linux 系统,桌面为KDE 时,在使用Konsole 时,光标的位置是错位的. 如下图效果  解决办法 用命令进入/home/cfox/.kde/share/apps/konsole 修改S ...

  4. maven加速镜像

    <mirror> <id>repo3</id> <mirrorOf>central</mirrorOf> <name>Human ...

  5. Redis的安装和部署(windows )

    Redis是一个开源的试用ANSI C语言编写的.遵守BSD协议.支持网络.可基于内存可持久化的日志型.key-value数据库.通常被称为数据结构服务器. redis的数据类型有:字符串(strin ...

  6. vue02—— 动画、组件、组件之间的数据通信

    一.vue中使用动画 文档:https://cn.vuejs.org/v2/guide/transitions.html 1. Vue 中的过渡动画 <!DOCTYPE html> < ...

  7. Python-常见错误梳理

    1. takes exactly 1 argument (2 given) 出现此错误一般是在某对象调用类的某方法时出现.因为在python中某类的实例对象调用方法时,是首先将自身作为一个参数传入此方 ...

  8. python正则中如何匹配汉字以及encode(‘utf-8’)和decode(‘utf-8’)的互转

    正则表达式: [\u2E80-\u9FFF]+$ 匹配所有东亚区的语言  [\u4E00-\u9FFF]+$ 匹配简体和繁体  [\u4E00-\u9FA5]+$ 匹配简体  <input ty ...

  9. mysql数据库的导入导出命令

    1.备份一个数据库 mysqldump -h localhosot -uroot -ppassword 数据库名>数据库所在路径(路径+数据库名.sql) 注意:导出的数据库文件.sql文件不能 ...

  10. IntelliJ IDEA(2018)安装和破解。

    一.下载并安装, IntelliJ IDEA的官网:https://www.jetbrains.com           二.破解. 百度下载一个 JetbrainsCrack-2.6.2.jar ...