贪心例题集

二进制枚举子集 阅读详情

贪心


POJ3617贪心


POJ3617

描述

给定长度为N的字符串s,要构造一个长度为N的字符串T。期初,T是一个空串。
然后以下操作:

  • 从S的头部删除一个字符,加到T的尾部。

  • 从S的尾部删除一个字符,加到T的尾部。

目标是要使构造的字典序尽可能小。

思路

  • 我们很容易想到每次就看字符串S的头尾,把小的删除掉放到T的尾部就好。但是存在一个问题,当头尾的字符一样的时候,就必须要比较下一个字符的大小。
  • 所以我们就建立把S反过来为S2,S2与S比较,S小就把S的头字符删除;反之就把S2的头字符删除。

AC代码

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

    const int maxn = 2010;
    char s[maxn];
    char s2[maxn];
    char ans[maxn];
    int n;

    int strcmp(const char *src,const char *dst,int i,int j)
    {
        int flag = 0;
        for(; i < n && j < n ; i ++, j ++)
        {
            if(src[i] < dst[j])
                return 1;
            else if(src[i] > dst[j])
                return -1;
        }
        return 0;
    }

    int main()
    {
        cin >> n ;

        for(int i = 0; i < n; i ++)
        {
            cin >> s[i];
            s2[n-1-i] = s[i];
        }
        //cout<<s<<" "<<s2<<endl;

        //cout<<strcmp(s,s2,1,0)<<endl;

        //反过来比较
        int i,j,Index = 0;
        for(i = 0,j = 0; i < n && j < n && Index < n;Index ++)
        {
            if(strcmp(s,s2,i,j) > 0)
            {
                ans[Index] = s[i];
                i ++;
                //cout<<"a"<<endl;
            }

            else
            {
                ans[Index] = s2[j];
               // cout<<"b"<<endl;
                j ++;
            }
        }

        j = 1;
        for(int i = 0; i < n ;i ++)
        {
            if(j == 80)
            {
                cout<<ans[i]<<endl;
                j = 1;
            }

            else
            {
                cout<<ans[i];
                j ++;
            }

        }
        printf("\n");
        return 0;
    }

POJ3069_Saruman’s Army

http://poj.org/problem?id=3069

题意

  • 直线上有N个点,我们需要标记一些点。被标记的点有一个覆盖范围r。现在我们需要求最少的标记次数,并且使得每个点都被覆盖。(自己能覆盖自己)

思路

  • 我们从最左边考虑,设点为x0。要使得x0被覆盖,我们是想找到x0右边(包括x0)最远的一个能够覆盖到x0的点xi来标记,因为选xi左边的点没有任何好处,既然要覆盖x0,那就选最远的能够覆盖的点就是最好的选择。

  • 然后,按照这个思路我们就能往下找,找标记的点的右边第一个不能被覆盖的点作为x0,以此类推找下去就能得到最优解。

AC代码

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

    const int maxn = 1010;
    int a[maxn];

    int main()
    {
        int r,n,ans;
        while(scanf("%d%d",&r,&n)!=EOF && !(r==-1 && n == -1))
        {
            for(int i = 0; i < n ;i ++)
                scanf("%d",&a[i]);

            sort(a,a+n);

            ans = 0;
            int i,j,z;
            for(i = 0; i < n ;)
            {
                for(j = i+1; j < n ;j ++)
                {
                    //距离过大 
                    if(a[j] - a[i] > r)
                    {
                        //j-1的位置标记 
                        ans ++; 

                        //寻找下一个没有被覆盖的点  
                        for(z = j; z < n ;z ++)
                        {
                            if(a[z] - a[j-1] > r)
                            {
                                i = z;
                                break;
                            }
                        }

                        //完全覆盖了 
                        if(z == n)
                            i = n;

                        break;
                    }
                }

                if(j == n)
                {
                    ans ++;
                    break;
                }

            }

            printf("%d\n",ans);
        }
        return 0;
    } 

POJ3253_Fence Repair

http://poj.org/problem?id=3253

题意

  • 现需将一块木板切成N-1块,每一块长度为Li。模板长度一定等于每一块的长度的和。每次切的时候的花费是切之前的木板长度,比如长为8,8和5,那么花费是第一次切成13和8,花费21,第二次把13切成8和5,花费13,总花费34。现在要求最少花费。

思路

  • 因为切的次数是一定的(n-1),我们想要花费少,就要尽可能地把大木板先切出来,也就是小木板放到后面切。
  • 但是正向我们切的时候不知道该怎么切,所以需要逆向思维,自底向上,由小木板组成大木板。对应于哈夫曼树,其实这个题就是要把小木板放到尽可能放到深度更深的点,大模板尽量放到深度浅的点。这样总的花费是最小的。
  • 逆向,假设已经切好了,需要拼接成一个大木板。我们每次选取最小的两个木板拼接,放入木板堆,然后再选两个最小的拼,以此类推。

AC代码


    #include <iostream>
    #include <cstdio>
    #include <algorithm> 
    #include <set>
    using namespace std;

    typedef long long LL;

    int main()
    {

        multiset<LL > s;
        multiset<LL >::iterator it1,it2;
        LL n,tmp;
        LL ans = 0;
        scanf("%lld",&n);
        for(int i = 0; i < n ;i ++)
        {
            scanf("%lld",&tmp);
            s.insert(tmp);      
        }

        it1 = s.begin();
        it2 = ++it1;
        it1--;
        while(s.size() > 1)
        {
    //      cout<<s.size()<<endl;
            tmp = *it1 + *it2;
            ans += tmp;
    //      cout<<*it1<<" "<<*it2<<endl;
            s.erase(it1);                //参数是迭代器 
            s.erase(it2);
            s.insert(tmp);
    //      cout<<s.size()<<endl;
            it1 = s.begin();
            it2 = ++it1;
            it1--;
        }

        printf("%lld",ans);

        return 0;
    }

VijosP1123均分纸牌

描述

有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若于张纸牌,然后移动。

移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。

现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。

例如 N=4,4 堆纸牌数分别为:
① 9 ② 8 ③ 17 ④ 6
移动3次可达到目的:
从 ③ 取 4 张牌放到 ④ (9 8 13 10) -> 从 ③ 取 3 张牌放到 ②(9 11 10 10)-> 从 ② 取 1 张牌放到①(10 10 10 10)。
格式
输入格式

N(N 堆纸牌,1 <= N <= 100)
A1 A2 … An (N 堆纸牌,每堆纸牌初始数,l<= Ai <=10000)
输出格式

所有堆均达到相等时的最少移动次数。
样例1
样例输入1

4
9 8 17 6

样例输出1

3

思路

  • 首先题目说了纸牌总数是N的倍数,那么平均值一定是整数。
  • 然后,因为只能从相邻的纸牌堆中拿,而且要最少次数,也就是说不能左边给了右边,右边又给左边。
  • 所以我们就遍历一遍,每次如果数量就是平均值,继续;如果不是平均值,我们假设从逻辑上来讲一定从右边拿牌,也就是说,a[i+1] -= 平均值 - a[i],如果a[i]比平均值小,那么就是右边的牌减少,如果a[i]比平均值大,右边减去负数增大,也就是左边的牌传给了右边。
  • 这样每次就不用考虑左边的情况,因为左边那么给了你,要么你已经在上一步给了左边。

AC代码

    #include<iostream>
    #include<cstdio>
    using namespace std;

    int main()
    {
        int N;
        scanf("%d",&N);
        int a[110];
        int sum = 0;
        for(int i = 0; i < N ;i ++)
        {
            scanf("%d",&a[i]);
            sum += a[i];    
        } 

        //求平均值  因为是倍数 所以一定是整数 
        int junzhi = sum / N; 
        int ans = 0;

        for(int i = 0;i < N ;i ++)
        {
            if(a[i] == junzhi)
                continue;

            //因为只能从相邻的取 
            //都从右边取 ,从右边取负,表示传给右边 
            a[i+1] -= junzhi - a[i];
            ans ++;
        }

        printf("%d\n",ans);

        return 0;
    }

贪心算法(附蓝桥杯例题) 贪心算法(Greedy Algorithm)是一种‌通过局部最优选择逐步推导全局最优解‌的算法思想‌4。‌无后效性‌:当前决策不影响后续状态‌最优子结构‌:局部最优解能推导全局最优解适用于贪心算法的问题往往具有明确的‌排序性质‌和‌可分解性‌,如合并问题、区间调度等‌45。 阅读详情

相关推荐

贪心问题以及经典例题

局部最优选择:在每一步决策中,贪心算法都选择当前看起来最优的方案,而不考虑这个选择对未来的影响。全局最优解:贪心算法的目标是找到问题的全局最优解,即在所有可能的解决方案中,最优的那一个。

m0_49844997的博客 745

Best Cow Line

题目描述: 给定长度为N的字符串S,要构造一个长度为N的字符串T。期初,T是一个空串,随后反复进行下列任意操作。 从S的头部删除一个字符,加到T的尾部 从S的尾部删除一个字符,加到T的尾部 目标是要构造字典序尽可能小的字符串T。 字典序:从前到后比较两个字符串大小的方法。首先比较第一个字符,如果不同,则第一个字符小的字符串更小,如果相同,则继续比较第二个字符……如此继续,来比较整个字符串的大小。 ...

weixin_44915226的博客 325

p6880880_112000_Linux-x86-64.zip(11.2.0.3.21)

p6880880_112000_Linux-x86-64.zip(11.2.0.3.21) 最新Opath补丁安装软件,注意是64位的操作系统。请配合最新补丁进行安装p29255947_112040_Linux-x86-64.zip、p29141056_112040_Linux-x86-64.zip

字典序最小问题(POJ3617)

题目大意:给定长度为N的字符串S,要构造一个长度为N的字符串T。起初,T是一个空串,随后反复进行下列任意操作。 从S的头部删除一个字符,加到T的尾部 从S的尾部删除一个字符,加到T的尾部 目标是构造字典序尽可能小的字符串。 输入: 6 ACDBCB 输出 ABCBCD 解题思路: 这道题我们很容易想到,不断取开头或者结尾最小的一个字母放到T中就可以了。这个思路是正确的,不过我们要针对开头和结尾相同...

小飞猪的博客 1258

从光猫到机顶盒:H10G-13融合网关双系统网络配置全解析(含超密获取技巧)

本文详细解析了中国移动H10G-13融合网关的双系统网络配置,涵盖光猫路由与安卓电视盒子的协同工作。通过晶晨S905L3芯片的优化,设备实现高效网络接入与安卓9.0系统的定制化应用,特别适合酒店和民宿行业的智能化改造。文章还提供了超密获取技巧和线刷固件包的实用指南。

weixin_42525264的博客 945

【上海大学计算机组成原理实验报告】七、程序转移机制

学习实现程序转移的硬件机制//掌握堆栈寄存器的使用//手动方式实现子程序调用转移过程//手动方式实现子程序返回转移过程//编程实现`OUT`寄存器交替显示`11`和`55`//若要求`11`和`55`各显示`50`次后停机,应该如何修改程序?//根据实验指导书的相关内容,实验箱系统的程序转移硬件机制在于,当`LDPC`有效时,如果此时`DUBS`上的值就是转移的目标地址,则此目标地址被打入`PC`,从而实现程序的转移;若`LDPC`为`0`是附带条件的,就形成“条件转移”。

HackerKevon的博客 2471

字典序最小问题

字典序最小问题 /* 字典序最小问题 给一个定长为N的字符串S,构造一个字符串T,长度也为N。 起初,T是一个空串,随后反复进行下列任意操作 从S的头部删除一个字符,加到T的尾部 从S的尾部删除一个字符,加到T的尾部 目标是最后生成的字符串T的字典序尽可能小 1≤N≤2000 字符串S只包含大写英文字母 输入:字符串S 6 A C D B C B 输出:字符串T ABCBCD POJ - 3617 要求每80个字符换行输出 */ package _90贪心; import java.

无雨 516

什么是plm系统?-数字化转型网

当今世界,产品研发能力是企业在激烈的市场竞争中保持战略优势的核心竞争力之一。如何有效地缩短产品研发周期、改善产品服务的设计迭代流程、有效降低产品的研发成本,也是企业面临的主要问题之一。PLM(Product Lifecycle Management,产品生命周期管理)在优化产品研发的全管理流程、增强企业产品的市场竞争力方面具有关键的作用。

cxo17757154043的博客 882

贪心法解决最小字典序问题

问题描述: 给定一个长度为n的字符串S,构造一个字符串T,长度也为n;起初,T是一个空字符串,随后反复进行以下操作: 1、从S的头部删除一个字符,加到T的尾部。 2、从S的尾部删除一个字符;加到T的尾部。 目标是:最后生成的字符串T的字典序尽可能小。 解题思路: 每次选取的时候将头尾两个字符对比,将字典序小的删除并添加到T中。我们可以将S给逆序,保存为另一个字符串。然后将逆序的S和正序的S首字符的...

覃会程的博客 2024

对西安交大轴承数据集XJTU-SY_Bearing_Datasets进行读取和处理:

故障诊断,对西安交大轴承数据集XJTU-SY_Bearing_Datasets进行读取和处理

qq_44757503的博客 6060

轻量级替代方案:用AIFlowy + Ollama在本地快速搭建一个可用的AI智能体平台

本文介绍了如何使用AIFlowy和Ollama在本地快速搭建轻量级AI智能体平台,涵盖从环境准备到智能体集成的全流程。通过简化部署步骤和优化性能,15分钟内即可完成搭建,适用于原型验证和小团队协作,显著提升开发效率。

weixin_29207533的博客 219

3.8ACM课程总结(1)——贪心

贪心算法 利用贪心策列解题,需要解决两个问题: 1、该题是否适合于用贪心策略求解; 2、如何选择贪心标准,以得到问题的最优/较优解; 解决问题 1、最优装载问题 应该是最简单的一类贪心了,只要将重量轻者先装,达到最大载重就可以了。 2、背包问题(可分割的) 按照性价比来排序(因为挑选轻的或者是挑价值高的都有反例可以证明) ...

Ashen1_的博客 298

tkinter使用label视频播放

tkinter是python的界面开发包 使用tkinter显示视频流的一个办法是使用label来逐帧显示图片。 from Tkinter import * from PIL import ImageTk, Image import cv2 root = Tk() # Create a frame app = Frame(root, bg="white") app.grid() # Create a label in the frame lmian = Label(app) lmain.grid(

六十英里的专栏 5526

例题集 贪心算法

最大金钱 最多安排 最小拼接字典序 最多雪糕 1.最大金钱 题目: 两个数组:cost数组代表做每个项目需要花费多少钱;profit数组代表做每个项目能获得多少利润(纯利,即拿回的钱是花费的钱+利润)。默认里面都没有负数。 有一个启动资金w,一次只能做一个项目,不能并行。 k:最多做k个项目 问:最终获得的最后钱数 思路 1.用一个Node类保存cost、profit信息 2.全部分别丢进cost的小根堆(优先级队列) 3.判断有多少可以从cost的小根堆丢进profit的大根堆(优先级队列) 4.判断.

jiangyinglong123456的博客 284

S7-200SMART通过表格指令实现模拟量信号滑动平均值滤波的具体方法

S7-200SMART通过表格指令实现模拟量信号滑动平均值滤波的具体方法

Robot_PLC_HMI_Automation 6724

OpenCV实战系列——图像线条提取

基于内容的图像分析,需要从构成图像的像素集合中提取有意义的特征。轮廓、线条、区域等是基本的图像基元,可用于描述图像中包含的元素。本节将介绍如何提取重要的图像线条特征。

m0_58523831的博客 1万+

反悔贪心-第二次学习总结

适用场景需要局部调整的问题数据结构优先队列(堆),通常小根堆用于维护最小值,大根堆用于维护最大值时间复杂度O (n log n)(排序和堆操作)关键步骤排序→遍历→堆维护→动态调整常见问题应对:最后一天的处理:确保堆中所有元素都被正确卖出(通过循环条件或额外处理)多重约束问题:扩展堆的存储结构,同时维护多个维度的信息复杂度优化:使用更高效的堆实现或平衡树结构。

qq_40258545的博客 1157

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

贪心算法典型例题

贪心是算法中一种特别基础和重要的思想,下面从几个例题中开始讲解贪心的思想。 1. 分糖果(leetcode455) 题目:已知一些孩子和一些糖果,每个孩子有需求因子g,每个糖果有大小s,当某个糖果的大小s&amp;amp;amp;gt;=某个孩子的需求因子g时,代表该糖果可以满足该孩子,求使用这些糖果,最多能满足多少孩子(注意,某个孩子最多只能用1个糖果满足) 思考: 当某个孩子可以被多个糖果满足时,是否需要...

bajin7353的博客 3万+

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

详解贪心算法(Python实现贪心算法典型例题)

贪心算法 贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。 贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。 贪心算法的要素 贪心选择 贪心选择是指所求问题的整体最优解可以通过...

一个平平无奇的甜妹 4万+

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

贪心算法的几种经典例题

什么是贪心算法 贪心算法是一种在解决问题的过程中追求局部最优的算法,对于一个有多种属性的事物来说,贪心算法会优先满足某种条件,追求局部最优的同时希望达到整体最优的效果。以背包问题为例,可以放在背包中的物体有它的重量和价值两种属性,背包的容量也是有限的,我们希望得到一种价值最大的物品摆放方式,如果我们倾向于重量贪心,那么在摆放物品的时候会优先放重量小的,但这和我们追求的价值最优没有关系,自然不能采用...

马一凡的博客 5万+

算法学习笔记:23.贪心算法之活动选择问题 ——从原理到实战,涵盖 LeetCode 与考研 408 例题

《贪心算法解活动选择问题全攻略》摘要:活动选择问题是贪心算法的经典应用,要求在有限资源下选择最多互不冲突的活动。本文详细解析了贪心策略的核心思路(选择结束最早活动)、算法步骤及正确性证明,并通过LeetCode例题(435无重叠区间、646最长数对链)和考研408真题进行实战演示。文章还探讨了资源约束下的扩展解法,分析了时间复杂度(O(nlogn)),并提供了Java实现代码。最后总结了该算法在会议安排、任务调度等场景的应用价值,强调掌握贪心选择性质和最优子结构的重要性。

CSBIGDOG的博客 1760

贪心(细致讲解+例题分析)

贪心算法(英语:greedy algorithm),是用计算机来模拟一个「贪心」的人做出决策的过程。这个人十分贪婪,每一步行动总是按某种指标选取最优的操作。而且他目光短浅,总是只看眼前,并不考虑以后可能造成的影响。 可想而知,并不是所有的时候贪心法都能获得最优解,所以一般使用贪心法的时候,都要确保自己能证明其正确性。

BoBoo文睡不醒 1288

【贪心思想】兄弟总爱贪小便宜,原来是把贪心算法掌握得如此熟练【经典例题讲解】

⭐️引言⭐️ 大家好,我是执梗。最近通过我这篇蓝桥全解析文章——蓝桥全解析【内附资源】来找我咨询的兄弟很多。他们都有一个问题——贪心是不是最难的算法呀?答案确实是肯定的,那有的兄弟们就觉得那我是不是要把其他的算法都学熟练以后再来学习贪心呢?这个答案却是否定的。贪心确实是没有套路可言,与其说它是算法,更不如说贪心更像是一种思想。正所谓人不为己天诛地灭,人有贪嗔痴三念,贪心这件事上每个人都是有天赋的,所以我们从开始学习算法就要训练一种贪心的思想。给个小剧场让大家代入一下 ⭐️小剧...

执梗的博客 1675

贪心算法例题

贪心算法经典例题解析 贪心法:遵循某种规律,不断贪心的选取当前最优策略的算法设计方法。 例一:分糖果 已知一些孩子和一些糖果,每个孩子有需求因子g,每个糖果有大小s,当某个糖果的大小s >= 某个孩子的需求因子g时,代表该糖果可以满足该孩子;求使用这些糖果,最多能满足多少孩子?(注意,某个孩子最多只能用1个糖果满足)例如,需求因子数组g = [5, 10, 2, 9, 15, 9];糖果大小数组s = [6, 1, 20, 3, 8];最多可以满足3个孩子 思考:   1、当某个孩子可以被多个糖果

xiaobaidad的博客 3669

贪心思想及例题

贪心(greedy)思想:一个问题拆解成多个步骤,每个步骤采用最优的解法(叫局部最优),不考虑对别的步骤的影响。 最少硬币问题: 题目描述:某人带着3种面值的硬币去购物,有1元、2元、5元的,硬币数量不限;他需要支付M元,问怎么支付,才能使硬币数量最少? 思路:根据生活常识,第一步应该先拿出面值最大的5​ 元硬币,第二步拿出面值第二大的2​ 元硬币,最后才拿出面值最小的1​ 元硬币。在这个解决方案中,硬币数量总数是最少的。 #include<bits/stdc++.h> usi...

weixin_46438976的博客 2199

贪心算法——思路与例题

那么如何实现呢,具体就是对于第一个国家,那么这个值就是a-b-c,对于第二个国家,这个值就是b-a-c,对于第三个国家,这个值就是c-a-b,可以看出,其实就是相对值,也就是这个事件发生时,对第一个国家,第二个国家,第三个国家的胜利的贡献值。那么我们应该倒序考虑,这样我们可以选择的巧克力种类才最多,因为在第x天时,我们选择的巧克力的保质期一定是大于等于x的,这就意味着,当在1—x天里的任意一天时,可以选择的巧克力种类最多。题目分析:现在一共有n种巧克力,每种巧克力包含三个信息:价格,保质期,数量。

2301_79862041的博客 2299
上一篇: ssh三层框架——上传文件(大小格式筛选+json返回相对地址)
下一篇: 阿里云网站建设课程笔记
WaveBridge
博客等级 码龄10年 8粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值