POJ3614 Sunscreen 贪心入门

题目大意

给出一些区间和一些点,一个点如果在一个区间内,那么此两者可以匹配。问匹配数最大是多少。

题解

这样的题我们一般都是站在区间上去找与其配对的点。我们可以得到如下性质:

对于一段区间\([l_1,r_1]\)的任意两点\(a,b, a<b\),它们对于任意一个区间\([l_2,r_2],l_2<l_1\),\(a\in[l_2,r_2]\)的可能性(以后用P表示)\(P(a\in[l_2,r_2])>P(b\in[l_2,r_2])\)。

什么叫“可能性大”呢?暂且规定如果事件A不可能发生的自变量的取值范围比事件B的少一个“无限”,则事件A成立的可能性比B的大。本题中,如果我们让\(a\)位于左区间,那么\(a\notin [l_2,r_2]\Rightarrow a\in(-\infty ,l_2)\cup(r_2,b)\)。而如果我们让\(b\)位于左区间,那么\(b\notin [l_2,r_2]\Rightarrow b\in(-\infty,l_2)\cup(r_2,\infty)\)后者有两个无穷,前者有一个无穷,故性质成立。其它的结论通过类似的方式推导,无法消掉一个无穷,故此方法是对的。

因此,我们可以得到推论:

处理区间集合\(R\)和点集\(A\)时,先将左端点最靠右的区间\(r\)与属于该区间且最靠右的点\(a\)配对,然后子问题\(R-\{r\},A-\{a\}\)所能配对的数量是最多的。

凭什么就要选左端点最靠右的区间?因为先选了它并不会使结果变差。

由此我们就得到了贪心算法:给点按位置从大到小排序,区间按左端点位置从大到小排序,然后按以上黑体字做即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int MAX_POINT = 3000, MAX_RANGE = 3000;

struct Point
{
    int Num, P;
}_points[MAX_POINT];

struct Range
{
    int L, R;
}_ranges[MAX_RANGE];

bool CmpPoint(Point& a, Point& b)
{
    return a.P > b.P;
}

bool CmpRange(Range& a, Range& b)
{
    return a.L > b.L;
}

int main()
{
    int totRange, totPoint;
    scanf("%d%d", &totRange, &totPoint);
    for (int i = 1; i <= totRange; i++)
        scanf("%d%d", &_ranges[i].L, &_ranges[i].R);
    for (int i = 1; i <= totPoint; i++)
        scanf("%d%d", &_points[i].P, &_points[i].Num);
    sort(_ranges + 1, _ranges + totRange + 1, CmpRange);
    sort(_points + 1, _points + totPoint + 1, CmpPoint);
    int ans = 0;
    for (int i = 1; i <= totRange; i++)
    {
        for (int j = 1; j <= totPoint; j++)
        {
            if (_points[j].Num > 0 && _ranges[i].L <= _points[j].P && _points[j].P <= _ranges[i].R)
            {
                ans++;
                _points[j].Num--;
                break;
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}

原文地址:https://www.cnblogs.com/headboy2002/p/9074959.html

时间: 2024-10-08 00:45:39

POJ3614 Sunscreen 贪心入门的相关文章

贪心入门——活动安排问题

贪心入门的几个例题来自51nod 问题描述 有若干个活动,第i个开始时间和结束时间是[Si,fi),只有一个教室,活动之间不能交叠,求最多安排多少个活动? 输入 第1行:1个数N,线段的数量(2 <= N <= 10000) 第2 - N + 1行:每行2个数,线段的起点和终点(-10^9 <= S,E <= 10^9) 输出 输出最多可以选择的线段数量. 输入示例 3 1 5 2 3 3 6 输出示例 2 求解思路 按照活动的结束时间早的优先 算法代码 #include <

poj3614 Sunscreen 【优先队列】

题意 有C个奶牛去晒太阳 (1 <=C <= 2500),每个奶牛各自能够忍受的阳光强度有一个最小值和一个最大值,太大就晒伤了,太小奶牛没感觉. 而刚开始的阳光的强度非常大,奶牛都承受不住,然后奶牛就得涂抹防晒霜,防晒霜的作用是让阳光照在身上的阳光强度固定为某个值. 那么为了不让奶牛烫伤,又不会没有效果. 给出了L种防晒霜.每种的数量和固定的阳光强度也给出来了 每个奶牛只能抹一瓶防晒霜,最后问能够享受晒太阳的奶牛有几个. 那么将奶牛按照阳光强度的最小值从小到大排序. 将防晒霜也按照能固定的阳光

POJ3614 Sunscreen 【贪心】

Sunscreen Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4204   Accepted: 1458 Description To avoid unsightly burns while tanning, each of the C (1 ≤ C ≤ 2500) cows must cover her hide with sunscreen when they're at the beach. Cow i has

【POJ3614】【USACO 2007 Nov Gold】 3.Sunscreen 贪心

题意: 有若干个区间,若干种数,每个数告诉你有多少个. 然后一个数可以被放到一个x∈该区间 的区间,问最多有多少个区间可以被放. 题解: 显然我们可以用二分图最大匹配做,水题. 但是此题有别的技巧. 就是我们可以贪心进行处理. 首先我们考虑到需要将两种数都排个序. 然后再进行贪心. 一种错误的贪心法是单调队列式贪心,就是记录个top,然后单调往后推. 这个不仔细想还不知道它是错的. 额,至于卡它的数据,,我可以提供给你一个错误代码和一个拍子,你们可以自己拍一组数据出来,很高效. 这里贴一份错误代

poj3614 Sunscreen【贪心】

Sunscreen Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11772   Accepted: 4143 Description To avoid unsightly burns while tanning, each of the C (1 ≤ C ≤ 2500) cows must cover her hide with sunscreen when they're at the beach. Cow i ha

[贪心入门]活动安排问题之二

有若干个活动,第i个开始时间和结束时间是[Si,fi),活动之间不能交叠,要把活动都安排完,至少需要几个教室? 分析:能否按照之一问题的解法,每个教室安排尽可能多的活动,即按结束时间排序,再贪心选择不冲突的活动,安排一个教室之后,剩余的活动再分配一个教室,继续贪心选择…… 反例: A:[1,2)  B:[1,4) C:[5,6) D:[3,7) 已经按结束时间排好顺序,我们会选择教室1: A C教室2:  B教室3:  D需要3个教室.但是如果换一种安排方法,我们可以安排AD在一个教室,而BC在

[贪心入门]活动安排问题

有若干个活动,第i个开始时间和结束时间是[Si,fi),只有一个教室,活动之间不能交叠,求最多安排多少个活动? 分析: 我们就是想提高教室地利用率,尽可能多地安排活动.考虑容易想到的几种贪心策略: (1) 开始最早的活动优先,目标是想尽早结束活动,让出教室.然而, 这个显然不行,因为最早的活动可能很长,影响我们进行后面的活动.例如活动开始和结束时间分别为[0, 100), [1,2) ,[2, 3), [3, 4),[4,5],安排[0,100)的这个活动之后,其他活动无法安排,可是最优解是安排

[HDU2037]贪心入门

今年暑假不AC Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 43909    Accepted Submission(s): 23436 Problem Description “今年暑假不AC?”“是的.”“那你干什么呢?”“看世界杯呀,笨蛋!”“@#$%^&*%...” 确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也

poj -3614 Sunscreen(贪心 + 优先队列)

http://poj.org/problem?id=3614 有c头奶牛在沙滩上晒太阳,每头奶牛能忍受的阳光强度有一个最大值(max_spf) 和最小值(min_spf),奶牛有L种防晒霜,每种可以固定阳光强度在某一个值,每种的数量是cover[i] ,每头奶牛只能用一瓶防晒霜,问最多有多少头奶牛能在沙滩上晒太阳. 理解题意之后还是挺好做的. 首先确定的贪心策略是,在满足min_spf的条件下,尽量用spf小的用在max_spf大的奶牛身上,用一个最小堆维护max_spf的最小值即可. 先对奶牛