贪心专题训练二

简介: 贪心专题训练二

1:会场安排问题

作者 陈晓梅

单位 广东外语外贸大学

题目来源:王晓东《算法设计与分析》


假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的

贪心算法进行安排。(这个问题实际上是著名的图着色问题。若将每一个活动作为图的一个

顶点,不相容活动间用边相连。使相邻顶点着有不同颜色的最小着色数,相应于要找的最小

会场数。)


输入格式:

第一行有 1 个正整数k,表示有 k个待安排的活动。

接下来的 k行中,每行有 2个正整数,分别表示 k个待安排的活动开始时间和结束时间。时间

以 0 点开始的分钟计。


输出格式:

输出最少会场数。


输入样例:

5
1 23
12 28
25 35
27 80
36 50


输出样例:

在这里给出相应的输出。例如:

3


代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB


解析:我们只需要用贪心算法对每一次遍历求最优解,最多进行n次就一定可以遍历晚所以时间,但是这是按结束时间排序会出现错误,必须得用开始时间排序,原因未知

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 10010;
int vis[N];
struct node
{
    int x, y;
    bool operator < (const node &a)
    {
        return x < a.x;
    }
}f[N];
int main()
{
    int n;
    cin >> n;
    for (int i = 0; i < n; i ++ ) cin >> f[i].x >> f[i].y;
    sort(f, f + n);
    int cnt = 0;
    for (int i = 0; i < n; i ++ )
    {
        if(!vis[f[i].y])
        {
            cnt ++;
            vis[f[i].y] = 1;
            int end = f[i].y;
            for(int j = i + 1; j < n; j ++ )
            {
                if(end <= f[j].x && !vis[f[j].y])
                {
                    end = f[j].y;
                    vis[f[j].y] = 1;
                }
            }
        }
    }
    cout << cnt;
    return 0;
}


2:h0145. 会议安排

作者 黄正鹏

单位 贵州工程应用技术学院


学校的礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办。小刘的工作就是安排学校礼堂的活动,每个时间最多安排一个活动。现在小刘有一些活动计划的时间表,他想尽可能的安排更多的活动,请问他该如何安排。


输入格式:

第一行是一个整型数m(m<100)表示共有m组测试数据。

每组测试数据的第一行是一个整数n(1<n<10000)表示该测试数据共有n个活动。

随后的n行,每行有两个正整数Bi,Ei(0<=Bi,Ei<10000),分别表示第i个活动的起始与结束时间(Bi<=Ei)


输出格式:

对于每一组输入,输出最多能够安排的活动数量。

每组的输出占一行


输入样例:

在这里给出一组输入。例如:

2
2
1 10
10 11
3
1 10
9 11
11 20


输出样例:

在这里给出相应的输出。例如:

2
2


代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB


#include <iostream>
#include <algorithm>
using namespace std;
const int N = 10010;
struct node
{
    int x, y;
    bool operator < (const node &a)
    {
        return y < a.y;
    }
}f[N];
int main()
{
    int T;
    cin >> T;
    while (T -- )
    {
        int n;
        cin >> n;
        for (int i = 0; i < n; i ++ ) cin >> f[i].x >> f[i].y;
        sort(f,f + n);
        int end = f[0].y;
        int cnt = 1;
        for (int i = 0; i < n - 1; i ++ )
        {
            if(end <= f[i + 1].x)
            {
                end = f[i + 1].y;
                cnt ++;
            }
        }
        cout << cnt << endl;
    }
    return 0;
}


3:最少失约

作者 usx程序设计类课程组

单位 绍兴文理学院


某天,诺诺有许多活动需要参加。但由于活动太多,诺诺无法参加全部活动。请帮诺诺安排,以便尽可能多地参加活动,减少失约的次数。假设:在某一活动结束的瞬间就可以立即参加另一个活动。


输入格式:

首先输入一个整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据首先输入一个正整数n,代表当天需要参加的活动总数,接着输入n行,每行包含两个整数i和j(0≤i<j<24),分别代表一个活动的起止时间。


输出格式:

对于每组测试,在一行上输出最少的失约总数。


输入样例:

1
5
1 4
3 5
3 8
5 9
12 14


输出样例:

2


代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

解析:我们只需要用贪心策略求出最优解,然后使用总活动数减去最优解就可以得到最少的失约策略

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 110;
struct node
{
    int x, y;
    bool operator < (const node &a)
    {
        return y < a.y;
    }
}f[N];
int main()
{
    int T;
    cin >> T;
    while (T -- )
    {
        int n;
        cin >> n;
        for (int i = 0; i < n; i ++ ) cin >> f[i].x >> f[i].y;
        sort(f,f + n);
        int end = f[0].y;
        int cnt = 1;
        for (int i = 0; i < n - 1; i ++ )
        {
            if(end <= f[i + 1].x)
            {
                end = f[i + 1].y;
                cnt ++;
            }
        }
        cout << n - cnt << endl;
    }
    return 0;
}


4:活动选择问题

作者 李廷元

单位 中国民用航空飞行学院


假定一个有n个活动(activity)的集合S={a1 ,a2 ,…,an},这些活动使用同一个资源(例如同一个阶梯教室),而这个资源在某个时刻只能供一个活动使用。每个活动ai都有一个开始时间si和一个结束时间fi,其中0<=si <fi<=32767。如果被选中,任务ai发生在半开时间区间[si,fi )期间。如果两个活动ai 和aj 满足[si ,fi)和[sj,fj)不重叠,则称它们是兼容的。也就说,若si >=fj或sj>=f i,则ai 和aj是兼容的。在活动选择问题中,我们希望选出一个最大兼容活动集。


输入格式:

第一行一个整数n(n≤1000);


接下来的n行,每行两个整数,第一个si ,第二个是fi (0<=si <fi<=32767)。


输出格式:

输出最多能安排的活动个数。


输入样例:

11
3 5
1 4
12 14
8 12
0 6
8 11
6 10
5 7
3 8
5 9
2 13


输出样例:

4


样例解释:

安排的4个活动为1 4, 5 7, 8 11和12 14。

代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1010;
struct node
{
    int x, y;
    bool operator < (const node &a)
    {
        return y < a.y;
    }
}f[N];
int main()
{
    int n;
    while (cin >> n)
    {
        for (int i = 0; i < n; i ++ ) cin >> f[i].x >> f[i].y;
        sort(f,f + n);
        int end = f[0].y;
        int cnt = 1;
        for (int i = 0; i < n - 1; i ++ )
        {
            if(end <= f[i + 1].x)
            {
                end = f[i + 1].y;
                cnt ++;
            }
        }
        cout << cnt << endl;
    }
    return 0;
}


5:删数问题

作者 任唯

单位 河北农业大学


有一个长度为n(n <= 240)的正整数,从中取出k(k < n)个数,使剩余的数保持原来的次序不变,求这个正整数经过删数之后最小是多少。

输入格式:

n和k

输出格式:

一个数字,表示这个正整数经过删数之后的最小值。


输入样例:

178543 4


输出样例:

13


代码长度限制

16 KB

时间限制

400 ms

内存限制

64 MB


解析:根据贪心策略,只要每一次选最优解,最终结果一定是最优解,这题刚开想到的策略是每次删掉最大的一个数,剩下的序列一定是最优解,通过反证法得出如果一个数中间有一串零的情况会出错,例如:30008 1最优解应该是8,所以后面思考力一下发现只要每次删除的数比后面一个数大就一定可以得到最优解

#include <iostream>
using namespace std;
int vis[250];
int main()
{
    string s;
    int n;
    cin >> s >> n;
    for (int i = 0; i < n; i ++ )
    {
        for (int j = 0; j < s.size(); j ++ )
            if(s[j] > s[j + 1] || j == s.size() - 1)
            {
                s.erase(s.begin() + j);
                break;
            }
    }
    while (s[0] == '0') s.erase(s.begin()); //  删除前导零
    cout << s;
    return 0;
}


目录
相关文章
|
存储 算法 C语言
数据结构——二叉树的基本概念及顺序存储(堆)
数据结构——二叉树的基本概念及顺序存储(堆)
209 0
|
JavaScript 前端开发
Element-ui 中表单(Form)验证数字值范围(大小)
Element-ui 中表单(Form)验证数字值范围(大小)
2529 0
Element-ui 中表单(Form)验证数字值范围(大小)
|
11月前
|
数据采集 中间件 Python
Scrapy爬虫框架-通过Cookies模拟自动登录
Scrapy爬虫框架-通过Cookies模拟自动登录
342 0
|
10月前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
369 16
|
存储
计算机组成原理(7)----CPU内部单总线数据通路
计算机组成原理(7)----CPU内部单总线数据通路
1230 0
|
10月前
|
搜索推荐 算法 C语言
【排序算法】八大排序(下)(c语言实现)(附源码)
本文继续学习并实现了八大排序算法中的后四种:堆排序、快速排序、归并排序和计数排序。详细介绍了每种排序算法的原理、步骤和代码实现,并通过测试数据展示了它们的性能表现。堆排序利用堆的特性进行排序,快速排序通过递归和多种划分方法实现高效排序,归并排序通过分治法将问题分解后再合并,计数排序则通过统计每个元素的出现次数实现非比较排序。最后,文章还对比了这些排序算法在处理一百万个整形数据时的运行时间,帮助读者了解不同算法的优劣。
339 7
|
安全 Java API
16 个最常用的 Java 实用程序类
【8月更文挑战第16天】
925 1
16 个最常用的 Java 实用程序类
|
机器学习/深度学习 分布式数据库
数据结构:二叉树经典例题(单选题)-->你真的掌握二叉树了吗?(第二弹)
数据结构:二叉树经典例题(单选题)-->你真的掌握二叉树了吗?(第二弹)
736 0
|
数据采集 搜索推荐 JavaScript
GitHub星标3500的Python爬虫实战入门教程,限时开源!
爬虫的全称为网络爬虫,简称爬虫,别名有网络机器人,网络蜘蛛等等。 网络爬虫是一种自动获取网页内容的程序,为搜索引擎提供了重要的数据支撑。搜索引擎通过网络爬虫技术,将互联网中丰富的网页信息保存到本地,形成镜像备份。我们熟悉的谷歌、百度本质上也可理解为一种爬虫。 如果形象地理解,爬虫就如同一只机器蜘蛛,它的基本操作就是模拟人的行为去各个网站抓取数据或返回数据。
|
人工智能 算法
图解:求逆序对数量(归并排序的应用)
图解:求逆序对数量(归并排序的应用)