P1842 [USACO05NOV]奶牛玩杂技
题意
一只奶牛有两个属性, 力量 Stg
和质量 Weg
. 将奶牛摞成一摞, 一只奶牛的压扁指数是其上所有奶牛质量和减它自己的力量, 求奶牛中压扁指数最大值的最小值.
分析
最大值最小, 一上来就写了个二分答案, 在想 Judge
函数怎么写的时候, 推式子直接推出了贪心策略, 遂大喜, 用贪心打了一遍过了, 以下是推式子过程.
两个属性都大的必在下
首先, 考虑两只相邻的牛. 如果一只牛 Stg
和 Weg
都比另一头大, 那它必然要放在下面, 因为如果换过来, 两头牛中最扁的会再扁
因为 , 所以表达式变成 , 整理得
由于 , , 所以表达式恒为正, 所以 Stg
和 Weg
都相对大的牛要在下面.
推广
考虑牛 放在牛 上的条件.
如果将上面的式子简单整理, 就会得到:
已知 ,
可以看出, 要小于 , 否则, 就可以整理出 (不成立).
得到:
必然是负数, 可知下面的牛 的和尽可能大, 推得上面的牛 尽量小, 相同时, 大的在下.
贪心策略就是以 为第一关键字, 升序排序, 以 为第二关键字, 升序排序.
实现
结构体 + 重载运算符 + sort, 最后 统计答案.
unsigned int n, tmp(0) /*质量前缀和*/;
int ans(-0x3f3f3f3f); //初始值足够小
struct Cow {
unsigned int Weg, Stg;
const bool operator<(const Cow &x) const {
if (this->Stg + this->Weg == x.Stg + x.Weg) { //第一关键字相同
return this->Weg < x.Weg; //以第二关键字为序
}
return this->Stg + this->Weg < x.Stg + x.Weg; //以第一关键字为序
}
} C[50005];
int main() {
n = RD();
for (register unsigned int i(1); i <= n; ++i) {
C[i].Weg = RD();
C[i].Stg = RD();
}
sort(C + 1, C + n + 1); //按 Cow 的规则升序排序
for (register unsigned int i(1); i <= n; ++i) {
ans = max(ans, (int)tmp - (int)C[i].Stg); //尝试更新答案
tmp += C[i].Weg; //累计质量
}
printf("%d\n", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
2020-02-02 洛谷网校:树形问题