TOJ 1611 Moo University - Financial Aid -- 线段树 + DP
来源:互联网 发布:食品行业数据 编辑:程序博客网 时间:2024/06/06 09:58
题目链接:http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1611
题目大意:给定c个二元组(x, y),要求从中选出n(n为奇数)个,满足这n个二元组的y之和不超过给定的f,而且x的中位数最大。输出最大的中位数。
分析:先将二元组(记为cow)按X排序,然后枚举每个X作为中位数。这时需要在X之前和X之后各选n / 2个数,因为已经按X排序,不管怎么选都可以满足X是中位数的条件,所以只需要各自选取Y最小的n / 2个数,判断它们的和是否满足不超过f这个条件。如果满足,X可行,否则不行。如果按X从大到小枚举X,那么遇到的第一个可行X即为答案。剩下的问题在于如何高效地求出最小的n / 2个数的和。
可以用动态规划解决这个问题。用一个长为n / 2的数组a记录以cow[i].X为中位数时前面最小的n / 2个Y,同时用dp[i]表示这些数中的最大值的下标,那么计算dp[i + 1]时,如果cow[i + 1].Y >= a[dp[i]],则dp[i + 1] = dp[i]。否则用cow[i + 1].Y替换a[dp[i]],同时计算出新的最大值下标也就是dp[i + 1]。这涉及单点更新及全区间的最大值查询,用线段树可以实现。至于求和,在计算dp[i]的时候顺便就可以求出来了。对于cow[i].X之后的数,再进行一次同样的操作。下面的代码中的dp保存的就是n / 2个数的和,因为最大值下标可以直接从线段树中读出,不需要另外存储。求出dp之后再进行一次线性扫描就可以求出答案了。
0 0
- TOJ 1611 Moo University - Financial Aid -- 线段树 + DP
- poj 2010 Moo University - Financial Aid (贪心+线段树)
- Moo University - Financial Aid
- POJ2010 Moo University - Financial Aid
- poj2010-Moo University-Financial Aid
- POJ2010 Moo University - Financial Aid
- poj2010 Moo University - Financial Aid
- Moo University - Financial Aid(2010)
- poj2010 Moo University - Financial Aid
- POJ2010-Moo University - Financial Aid
- POJ2010-Moo University-Financial Aid
- 【poj 2010】Moo University - Financial Aid 预处理dp
- POJ 2010 Moo University - Financial Aid
- poj 2010--Moo University - Financial Aid
- POJ-2010-Moo University - Financial Aid
- Moo University - Financial Aid - POJ 2010 二分
- POJ 2010 Moo University - Financial Aid
- POJ2010 Moo University - Financial Aid 优先队列
- 浏览器的一些区域和位置信息记录
- SVN svn-base 系统找不到指定的文件
- log4j.properties文件详解
- vSphere 5.1 (ESXi 5.1)开启并配置SNMP
- Jsoup解析Html教程
- TOJ 1611 Moo University - Financial Aid -- 线段树 + DP
- poj2159
- Android特效开发(可伸缩View带互相挤压效果 )
- 如何设置ESXi的SNMP
- C++中的智能指针
- UVa_644 - Immediate Decodability
- css ISO风格 按钮和Table 兼容IE
- 剑指offer面试题5
- KMP algorithm ---C++