BZOJ3174. [TJOI2013]拯救小矮人(dp)
题目链接
https://www.lydsy.com/JudgeOnline/problem.php?id=3174
题解
其实此题并不需要那么多YY的部分。
我们考虑若干个小矮人逃出的顺序。若跳出的 个小矮人依次为 ,那么我们一定可以将他们排序,使得对于任意的 满足 且按照该顺序依然能保证 个小矮人全部逃出。
证明如下:
若对于任意 ,有 ,且 比 先逃出,那么设 后面所有人的高度贡献为 , 与 之间的人的高度贡献为 , 为洞深,可得:
通过 ,我们可以推得:
通过 以及 ,我们可以推得:
由 可以得出: 比 先逃出依然是合法的。
这样,我们就证明了排序的正确性,那么就可以先排序再 dp 了。一个比较显然的状态是,我们设 表示考虑完排序后的前 个人,且已经逃走的人的 的值为 时,最多能逃走多少人。不过由于 可能很大,这样定义状态并不可行,因此我们需要把状态的第二维与状态本身的意义交换一下:设 表示考虑完排序后的前 个人,且已经逃走了 个人,这 个人的 的最小值。这样,我们就能在 的时间内完成这个 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; }
标签:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?