8.9 - 8. 贪心专题

---恢复内容开始---

1.HDU 2037

  给定每个电视节目Ti的时间段[s,e],问最多能收看几个完整节目。

选择不相交区间

  明显可以得出的是,如果节目1的时间区间在节目2的时间区间内,就不用考虑节目2了。

  然后需要选择最大节目数,先按结束时间e排序,如果e相同,s靠后的在前。然后选取e最小的节目。因为没有节目在T0之前,用它和T1比较,因为T1的结束时间靠后所以T1对后面的节目的“影响”更大(shenmegui)所以T0在前~

#include<bits/stdc++.h>

using namespace std;
struct l{
    int a;
    int b;
};

bool cmp(l x, l y){
    return x.b < y.b;

}

int main()
{
    int n;
    while(scanf("%d", &n) && n)
    {

        int ai, bi, sum = 1, k=0;//ai当前左端点  bi当前右端点
        l x[100];
        for(int i=0; i<n; i++)
        {
            scanf("%d%d", &x[i].a, &x[i].b);
        }

        sort(x,x+n,cmp);

        ai = x[0].a;
        bi = x[0].b;

        for(int i=k; i<n+k; i++)
        {
            if(x[i].a >= bi)
            {
                ai = x[i].a;
                bi = x[i].b;
                sum++;
            }
        }
        if(n == 0) sum--;
        printf("%d\n",sum);

    }
    return 0;
}

  --遇到的问题--

  一开始不会写cmp函数QAQQ  另外不用保存a端点 没改了

2.HDU 1009

  部分背包问题,类似还有 XDOJ 1087

#include<bits/stdc++.h>

using namespace std;

struct f{
    float a;
    float b;
    float div;
} x[1010];

bool cmp(f a, f b)
{
    return a.div > b.div;
}

int main()
{
    int m, n;
    while(scanf("%d%d", &m, &n) && m != -1 && n != -1)
    {
        double sum = 0.0;
        for(int i = 0; i < n; i++)
        {
            scanf("%f%f", &x[i].a, &x[i].b);
            x[i].div = x[i].a/x[i].b;
        }

        sort(x, x+n, cmp);

        for(int i = 0; i < n; i++)
        {
            if(m >= x[i].b)
            {
                sum += x[i].a;
                m -= x[i].b;
            }
            else
            {
                sum += m*x[i].div;
                break;
            }
        }
        printf("%.3lf\n", sum);
    }
    return 0;
}

  --遇到的问题--

  注意浮点数类型转换

3.POJ 3646

  对于每一个高度的头 尽量用高度足够的骑士中最低的杀死

#include<stdio.h>
#include<algorithm>
using namespace std;

int main()
{
    int m, n;
    while(scanf("%d%d", &n, &m) && (n || m))
    {
        int d[20158], k[20158];
        int sum = 0, j = 0;

        for(int i = 0; i < n; i++)
            scanf("%d", &d[i]);
        for(int i = 0; i < m; i++)
            scanf("%d", &k[i]);

        sort(d, d+n);
        sort(k, k+m);

        for(int i = 0; i < n; i++)
        {
            while(j <= m)//这里为什么不是小于呢  因为如果是  并且刚好m-1和n-1配对  那么也会出现j==m
            {
                if(k[j++] >= d[i])
                {
                    sum += k[j-1];
                    break;
                }
            }
        }

        if(j > m) printf("Loowater is doomed!\n");
        else printf("%d\n", sum);
    }
}

4.POJ 2709

  买尽可能少的“颜料套装”,来满足你需要的这N+1种颜料。

  对于多种颜色,每种取出一定的量来调出灰色。相当于把灰色颜料加到每种颜色需要的量上,最后用最多的那种+49/50。

  用很暴力的方法,每1ml灰色颜料加到 现在所需最少的三种之上,然后重新排序直到灰色全部调出。

#include<stdio.h>
#include<algorithm>
using namespace std;

int main()
{
    int n;
    while(scanf("%d", &n) && n)
    {
        int color[15];
        int grey, d;

        for(int i = 0; i < n; i++)
            scanf("%d", &color[i]);

        scanf("%d", &grey);

        sort(color, color+n);

        if(n > 3)
        {
            while(grey--)
            {
                color[0] ++;
                color[1] ++;
                color[2] ++; 

                sort(color, color+n);
            }
        }
        else color[2] += grey;

        printf("%d\n", (color[n-1] + 49)/50);
    }
}

  --遇到的问题--

  这样是可以过,但是数据大一些怎么办呢?

5.HDU 4296

  盖房子,某一层的PDV等于这一层之上所有重量之和(Σw j)减去这一层的可承重s i

  因为两层之间对调对于其他层没有影响,对于相邻两层a,b

  若a在上 用sa减去wb 剩下的s来承受sumw

  若b在上 用sb减去wa 剩下的s来承受sumw

#include<stdio.h>
#include<algorithm>

using namespace std;

struct f{
    int w, s;
} flr[201508];

bool cmp(f a, f b)
{
    return a.s - b.w > b.s - a.w;
}

int main()
{
    int n;
    while(scanf("%d", &n) != EOF)
    {
        int t;

        for(int i = 0; i < n; i++)
            scanf("%d%d", &flr[i].w, &flr[i].s);

        sort(flr, flr+n, cmp);

        long long sumw = 0, PDV = -flr[0].w;

        for(int i = n - 1; i > -1; i--)
        {
            if(sumw - flr[i].s > PDV)
                PDV = sumw - flr[i].s;
            sumw += flr[i].w;
        }
        //Êä³ö×î´ó·çÏÕ¡£¡£¡£¡£¡£¡£
        printf("%I64d\n", PDV);
    }
}

#include<stdio.h>
#include<algorithm>

using namespace std;

struct cow{
    int a, b;
} c[3000];

struct sunscreen{
    int spf, surplus;
} l[3000];

bool cmp1(cow x, cow y)
{
    if(x.b == y.b) return x.a < y.a;
    return x.b < y.b;
}
bool cmp2(sunscreen x, sunscreen y)
{
    return x.spf < y.spf;
}
int main()
{
    int n, m, k = 0, sum = 0;
    scanf("%d%d", &n, &m);

    for(int i = 0; i < n; i++)
    {
        scanf("%d%d", &c[i].a, &c[i].b);
    }
    for(int i = 0; i < m; i++)
    {
        scanf("%d%d", &l[i].spf, &l[i].surplus);
    }

    sort(c, c + n, cmp1);
    sort(l, l + n, cmp2);

    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            if(l[i].surplus && l[i].spf => c[i].a && l[i].spf <= c[i].b)
            {
                l[i].surplus--;
                sum++;
                break;
            }
        }
    }
    printf("%d\n", sum);
    return 0;
}

还没过

时间: 2024-08-01 22:45:42

8.9 - 8. 贪心专题的相关文章

【贪心专题】HDU 1009 FatMouse&#39; Trade (贪心选取)

链接:click here~~ 题意:老鼠准备了M磅猫食,准备拿这些猫食跟猫交换自己喜欢的食物.有N个房间,每个房间里面都有食物.你可以得到J[i]单位的食物,但你需要付出F[i]单位的的猫食. 计算M磅猫食可以获得最多食物的重量. [解题思路]贪心算法,求最优解.将J[i]/F[i]的值从大到小排列,每次取最大的,局部最优,达到全局最优,从而获得最大值. 代码: // 贪心策略,优先选择投资最大的房间,每选择一次,交换次数依次减少,最后的次数用于价值最小的 //注意精度转化:1.0*(int

【贪心专题】POJ 2456 Aggressive cows &amp;&amp; NYOJ 586 疯牛(最大化最小值 贪心+二分搜索)

链接: click here~~ 题意:农夫 John 建造了一座很长的畜栏,它包括N (2 <= N <= 100,000)个隔间,这些小隔间依次编号为x1,...,xN (0 <= xi <= 1,000,000,000). 但是,John的C (2 <= C <= N)头牛们并不喜欢这种布局,而且几头牛放在一个隔间里,他们就要发生争斗.为了不让牛互相伤害.John决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是什么呢? [解题

贪心专题

贪心: 原则是根据固定的一个或几个属性进行抉择.达到缩小规模的目的. split to steps and shrink scope 有点双端/DAG图的意思. reference 最近做的几个贪心题目 hdu 1052(田忌赛马) 根据马的速度排序,然后两边最小值,最大值的判断.这样做是因为两端的选择是唯一的,TJ最弱的马/最强的如果可以战胜那就是最好的抉择,不然就让其去当炮灰.(减少规模) #include<set> #include<cmath> #include<cs

贪心专题(不定期更新)

1.UVa 10382 - Watering Grass (贪心-区间覆盖) 题意:一块矩形草坪,给出若干个分布在中轴线上的喷水装置,喷水范围为圆形.问能否覆盖整个草坪,若能,求出最少的喷水装置数目. 思路:圆形半径小于等于草坪宽度一半的不用考虑:在剩下的喷水圆形区域中,求出对应覆盖草坪的矩形区块,之后则进行贪心处理:找出矩形区块[L,R]左侧L小于等于当前已覆盖区域的右侧POS的区块中,右侧R最大的那个,同时更新POS. 1 #include<iostream> 2 #include<

【贪心专题】HDU 1257 最少拦截系统&amp;&amp;HDU 2111 Saving HDU (选宝贝)

链接:click here~~ 题意: 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能超过前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹. 怎么办呢?多搞几套系统呗!你说说倒蛮容易,成本呢?成本是个大问题啊.所以俺就到这里来求救了,请帮助计算一下最少需要多少套拦截系统. [解题思路]: 直接模拟一边就可以,不知道想简单了还是数据

【贪心专题】HDU 1050 D - Moving Tables (移桌子)

链接:click here~ 题意:在一个长走廊里搬桌子,走廊的两侧都是房间,把桌子从一个房间搬到另外一个房间,走廊的宽度只能允许一个桌子通过,每次搬桌子需要10分钟(每一次允许再不交叉的走廊中同时搬桌子),问最少多长时间搬完! [解题思路] 这题也是想了好久,关键点:由于房间是奇偶分开的,所以先把他们换成连续的自然数,即n=(n-1)/2.这样对门的就变成一个编号了,这点是关键,感觉好厉害(因为房间是对称分布的,需要注意一下奇偶的情况.)利用房间号分割走廊,贪心实现求走廊的最大重叠数 这里使用

【贪心专题】POJ 1328 G - Radar Installation (区间覆盖)

链接:click here~~ 题意: Description Assume the coasting is an infinite straight line. Land is in one side of coasting, sea in the other. Each small island is a point locating in the sea side. And any radar installation, locating on the coasting, can only

【贪心专题】POJ 3258 River Hopscotch (最大化最小值 贪心+二分搜索)

链接:click here~~ [题意] 一条河长度为 L,河的起点(Start)和终点(End)分别有2块石头,S到E的距离就是L,河中有n块石头,每块石头到S都有唯一的距离,,现在要你移除其中的m块,使得具有最小间距的相邻两块石头之间的距离最大. [解题思路] 又是一道经典的二分搜索,跟前一道一样的思路,不过要注意的是:此题是移除其中的元素,从而达到最大化的最小值. 代码: #include <stdio.h> #include <string.h> #include <

【贪心专题】POJ 1323 &amp;&amp; HDU 1338 Game Prediction (贪心)

链接:click here~~ 题意: 有m个人,每个人有n张牌,牌点为在1~n*m中的不同的数.每回合每个人出一张牌,点数最大的那个人赢,给出A人初始时的n张牌的牌点,问A至少赢的次数. [解题思路] 看做两个人互相出牌,注意出牌的顺序,你有m张牌,我有m*(n-1)张牌,每次我都出比你大一点的牌,如果没有,出最小的m张牌(可以忽略), 每次出最大的.如果别人手中最大的小于你的.得分+1,而对方则选择最小的一个扔掉.如果对方最大的大于你手中最大的,对方会选择自己手中最小但是比你最大的大的牌丢掉

【贪心专题】HDU 1049 Climbing Worm (爬井趣题)

链接:click here~~ 题意: 题目大致意思是一个虫子掉在了一个n长度深的井中,然后它每分钟可以爬u长度,然后要休息一分钟,在此期间它会掉下d长度,问最终爬出井需要多久. 简单模拟: 代码: #include <stdio.h> #include <string.h> #include <math.h> #include <iostream> #include <algorithm> using namespace std; int ma