c++算法基础必刷题目——贪心

news2024/10/5 18:23:39

文章目录

  • 贪心
    • 1、拼数
    • 2、排座椅
    • 3、矩阵消除游戏
    • 4、华华听月月唱歌

贪心

  贪心算法(greedy algorithm ,又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解 。
  贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择

1、拼数

NC16783 拼数

题目描述

设有n个正整数(n ≤ 20),将它们联接成一排,组成一个最大的多位整数。
例如:n=3时,3个整数13,312,343联接成的最大整数为:34331213
又如:n=4时,4个整数7,13,4,246联接成的最大整数为:7424613

输入描述:

第一行,一个正整数n。
第二行,n个正整数。

输出描述:

一个正整数,表示最大的整数

示例1

输入
3
13 312 343

输出
34331213

解题思路:
1、贪心,将字符串按最优方案排序即可即,s1+s2>s2+s1

代码:

#include<bits/stdc++.h>
using namespace std;
bool cmp(string s1,string s2){
    return s1+s2>s2+s1;//不能简单地s1>s2,因为202和20200,应该把202放前面
}
int main(){
    int n;
    string s[25];
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>s[i];
    }
    sort(s,s+n,cmp);
    string ans;
    for(int i=0;i<n;i++){
        ans+=s[i];
    }
    cout<<ans<<endl;
}

2、排座椅

NC16618 排座椅

题目描述

  上课的时候总有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情。不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来之后,只有有限的D对同学上课时会交头接耳。
同学们在教室中坐成了 M 行 N 列,坐在第 i 行第 j 列的同学的位置是(i,j),为了方便同学们进出,在教室中设置了 K 条横向的通道,L 条纵向的通道。
于是,聪明的小雪想到了一个办法,或许可以减少上课时学生交头接耳的问题:她打算重新摆放桌椅,改变同学们桌椅间通道的位置,因为如果一条通道隔开了两个会交头接耳的同学,那么他们就不会交头接耳了。
请你帮忙给小雪编写一个程序,给出最好的通道划分方案。在该方案下,上课时交头接耳的学生对数最少。

输入描述:

  第一行,有 5 各用空格隔开的整数,分别是 M,N,K,L,D(2 ≤ N,M ≤ 1000,0 ≤ K < M,0 ≤ L < N,D ≤ 2000)M,N,K,L,D(2≤N,M≤1000,0≤K<M,0≤L<N,D≤2000)。
  接下来 D 行,每行有 4 个用空格隔开的整数,第 i 行的 4 个整数 Xi,Yi,Pi,Qi ,表示坐在位置 (Xi,Yi)与 (Pi,Qi)的两个同学会交头接耳(输入保证他们前后相邻或者左右相邻)。
输入数据保证最优方案的唯一性。

输出描述:

  共两行
  第一行包含 K 个整数,a1a2……aK,表示第 a1 行和 a1+1 行之间、第 a2行和第 a2+1行之间、…、第 aK 行和第 aK+1 行之间要开辟通道,其中 ai < ai+1,每两个整数之间用空格隔开(行尾没有空格)。
  第二行包含 L 个整数,b1b2……bK,表示第 b1 行和 b1+1 行之间、第 b2行和第 b2+1行之间、…、第 bK 行和第 bK+1 行之间要开辟通道,其中 bi < bi+1,每两个整数之间用空格隔开(行尾没有空格)。

示例1

输入
4 5 1 2 3
4 2 4 3
2 3 3 3
2 5 2 4

输出
2
2 4

说明

在这里插入图片描述
上图中用符号*、※、+ 标出了3对会交头接耳的学生的位置,图中3条粗线的位置表示通道,图示的通道划分方案是唯一的最佳方案。

解题思路:
1、先统计每一行和每一列上交头接耳的学生有多少对,按对数降序排序

2、按照K和L取最优的行和列,按升序排序,输出即可

代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,m,k,l,d;
    int a[1010]={0};
    int b[1010]={0};
    vector<vector<int>> v1,v2;
    cin>>n>>m>>k>>l>>d;
    for(int i=0;i<d;i++){
        int x,y,p,q;
        cin>>x>>y>>p>>q;
        if(x==p){
            b[min(y,q)]++;//列
        }else{
            a[min(x,p)]++;//行
        }
    }
    for(int i=1;i<1000;i++){
        v1.push_back({a[i],i});//行
        v2.push_back({b[i],i});//列
    }
    sort(v1.rbegin(),v1.rend());//从大到小排序
    sort(v2.rbegin(),v2.rend());//从大到小排序
    vector<int> v3,v4;
    for(int i=0;i<k;i++){
        v3.push_back(v1[i][1]);
    }
    for(int i=0;i<l;i++){
        v4.push_back(v2[i][1]);
    }
    sort(v3.begin(),v3.end());//答案从小到大排序
    sort(v4.begin(),v4.end());//答案从小到大排序
    for(int c:v3){
        cout<<c<<' ';
    }
    cout<<endl;
    for(int c:v4){
        cout<<c<<' ';
    }
}

3、矩阵消除游戏

NC200190 矩阵消除游戏

题目描述

  牛妹在玩一个名为矩阵消除的游戏,矩阵的大小是n行m列,第i行第j列的单元格的权值为ai,j ,牛妹可以进行k个回合的游戏,在每个回合,牛妹可以选择一行或者选择一列,然后将这一行或者这一列的所有单元格中的权值变为0,同时牛妹的分数会加上这一行或者这一列中的所有单元格的权值的和。
  牛妹想最大化她的得分,球球你帮帮她吧!

输入描述:

第一行三个整数n,m,k
接下来n行每行m个整数表示矩阵中各个单元格的权值。

输出描述:

输出一个整数表示牛妹能获得的最大分数。

示例1

输入
3 3 2
101 1 102
1 202 1
100 8 100

输出
414

解题思路:
1、暴力枚举行的消除方式,那么最多有215种方式,然后列的消除就用贪心法,取最优的列消除

2、我们可以用二进制枚举所有的消除方式,用1代表要消除的行,例如00101,代表第3行和第5行消除,那么从0~(1<<n)就可以枚举完所有的消除方案

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
int cnt(int val){//计算有多少个数字val二进制有多少个1
    int ans=0;
    while(val){
        ans++;
        val&=(val-1);
    }
    return ans;
}
signed main(){
    int n,m,k;
    int a[20][20]={0};
    cin>>n>>m>>k;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>a[i][j];
        }
    }
    int ans=0;
    for(int i=0;i<(1<<n);i++){//(1<<n)种行消除方式
        int t=k-cnt(i);
        int cu[20]={0};
        if(t<0)continue;
        int sum=0;
        for(int j=0;j<n;j++){
            if((i>>j)&1){//如果这位是1,那么该行就消除
                for(int k=0;k<m;k++){
                    sum+=a[j][k];
                }
            }else{//如果是0,那么就加在每一列里
                for(int k=0;k<m;k++){
                    cu[k]+=a[j][k];
                }
            }
        }
        sort(cu,cu+m);//排序后取最优的t列
        for(int j=m-1;j>m-1-t&&j>=0;j--){
            sum+=cu[j];
        }
        ans=max(ans,sum);//取最优解
    }
    
    cout<<ans<<endl;
}

4、华华听月月唱歌

NC23036 华华听月月唱歌

题目描述

  月月唱歌超级好听的说!华华听说月月在某个网站发布了自己唱的歌曲,于是把完整的歌曲下载到了U盘里。然而华华不小心把U盘摔了一下,里面的文件摔碎了。月月的歌曲可以看成由1到N的正整数依次排列构成的序列,它现在变成了若干个区间,这些区间可能互相重叠。华华想把它修复为完整的歌曲,也就是找到若干个片段,使他们的并集包含1到N(注意,本题中我们只关注整数,见样例1)。但是华华很懒,所以他想选择最少的区间。请你算出华华最少选择多少个区间。因为华华的U盘受损严重,所以有可能做不到,如果做不到请输出-1。

输入描述:

第一行两个正整数N、M,表示歌曲的原长和片段的个数。
接下来M行,每行两个正整数L、R表示第i的片段对应的区间是[L,R]。

输出描述:

如果可以做到,输出最少需要的片段的数量,否则输出-1。

示例1

输入
4 2
1 2
3 4

输出
2

示例2

输入
4 2
1 1
3 4

输出
-1

示例3

输入
10 5
1 1
2 5
3 6
4 9
8 10

输出
4

备注:
1≤L≤R≤10 9 ,1≤N≤109 ,1≤M≤105

解题思路:
贪心的思想,在可以选择的片段中,每次都选择最优的片段,即保证左边界可以连接得上,尽可能地扩展右边界

代码:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n,m;
    cin>>n>>m;
    vector<vector<int>> v;
    for(int i=0;i<m;i++){
        int a,b;
        cin>>a>>b;
        v.push_back({a,b});
    }
    sort(v.begin(),v.end());//区间按照升序排序
    int t=0;
    int g=0;
    int ans=0;
    int flag=1;
    for(int i=0;i<v.size();i++){
        if(v[i][0]<=t+1){//尽可能地往右扩充
            g=max(g,v[i][1]);
        }else{//选择最优的片段
            ans++;
            t=g;
            g=v[i][1];
            if(v[i][0]>t+1){//无法选择这个区间
                flag=0;
                break;
            }
        }
        if(g>=n){//提前退出
            ans++;
            break;
        }
    }
    if(flag&&g>=n){
        cout<<ans<<endl;
    }else{
        cout<<-1<<endl;
    }
}

是不是很简单呢?

刚接触肯定会觉得难,多些做题多些用,熟悉了就容易了,兄弟萌,加油!!!

文章尚有不足,感谢您的指正

感谢观看,点个赞吧

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/126272.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《图解TCP/IP》阅读笔记(第八章 8.5)—— WWW知多少?

8.5 WWW 看到这章的名字&#xff0c;对于日常上网冲浪的我们而言&#xff0c;应该是再熟悉不过了。这不就是常见网址前的那三个字母&#xff0c;号称万维网&#xff08;WWW&#xff0c;World Wide Web&#xff09;的东西吗? 确实&#xff0c;我们本篇文章就要介绍与之相关的…

Dimitra 2022: 年度回顾

大家好&#xff0c; 我首先要感谢 Dimitra 社区和我们所有的投资者在 2022 年期间的支持。俗话说&#xff0c;“这些都会过去”&#xff0c;2022 年的宏观加密环境尤其具有挑战性&#xff0c;一些非常糟糕的行为者给广泛的加密行业带来很多痛苦。 2023 年可能是监管框架最终显…

公司来了个新测试开发,一副毛头小子的样儿,哪想到......

最近公司来了个新同事&#xff0c;学历并不高&#xff0c;而且大学也不是计算机专业的&#xff0c;今年刚满25岁。。 本以为也是来干点基础的活混混日子的&#xff0c;结果没想到这个人上来就把现有项目的性能优化了一遍&#xff0c;直接给公司节省了不少成本&#xff0c;这种…

Qt通过QProcess启动进程并传递命令行参数

目录QProcess启动外部程序的两种方式依赖式分离式&#xff1a;启动进程前的预处理设置启动路径设置启动命令参数启动的状态更多说明Public FunctionsSignals设计一个拉起进程的程序基本设计思路效果图核心代码控件对象header file&#xff08;头文件&#xff09;member variabl…

java比较器

一、说明: Java中的对象&#xff0c;正常情况下&#xff0c;只能进行比较: 或 ! 。不能使用 >或 如何实现? 使用两个接口中的任何一个: Comparable 或 Comparator 二、Comparable的使用(自然排序) 1.Comparable接口的使用举例: 1.像string、包装类等实现了Comparable接口…

智能优化算法:协作搜索算法-附代码

智能优化算法&#xff1a;协作搜索算法 摘要&#xff1a;协作搜索算法( Cooperation search algorithm &#xff0c;CSA)是 Zhong-kai Feng等 于 2021 年提出的一种新型元启发式优化算法 。 该算法受现代企业团队协作行为的启发&#xff0c;具有寻优能力强&#xff0c;收敛速度…

Seata-AT模式数据源代理-JDBC中的关键知识点

背景 Seata 对业务无侵入是通过数据源代理实现的&#xff0c;从下图中可看出&#xff0c;数据源代理的实现涉及到 DataSource、Connection 以及 Statement&#xff0c;这几个关键知识属于 JDBC 的范畴&#xff0c;所以本篇从 JDBC 的视角对他们进行介绍。 一、JDBC 概述 JDBC…

【算法】面试题 - 回溯算法解题套路框架

回溯算法解题套路框架前言回溯算法的框架排列&#xff08;元素无重不可复选&#xff09;46. 全排列解析子集&#xff08;元素无重不可复选&#xff09;78. 子集解析组合&#xff08;元素无重不可复选&#xff09;77. 组合解析子集/组合&#xff08;元素可重不可复选&#xff09…

免费PDF转Word?有这几个网站就够了

如果您想使用 Word 文档&#xff0c;您可能需要将PDF 转换为 Word&#xff0c;以便您可以随意使用该文档。将 PDF 转换为 Word 的过程需要一个好的 PDF 转换器。在本文中&#xff0c;您将探索可用的 5个免费转换器&#xff0c;其中包括 奇客PDF 和PDF2Go。 最好的 6 个 PDF 转 …

【unity笔记】图解Vector3.SignedAngle()方法的返回值

首先看一下官方文档的说明&#xff1a; public static float SignedAngle (Vector3 from, Vector3 to, Vector3 axis); from测量角度差的源向量。to测量角度差的目标向量。axis一个向量&#xff0c;其他向量将绕其旋转。返回 from 与 to 之间的有符号角度&#xff08;以度为单…

CodeQL 源代码漏洞扫描

目录 1、下载配置 codeql 1.1 配置 codeql 1.2 配置 maven 2、测试 codeql 漏洞检测 2.1 构建 codeql 查询数据库 2.2 漏洞检测 测试环境&#xff1a;centos7 jdk11 maven 1、下载配置 codeql 1.1 配置 codeql 下载安装 codeql-cli: https://github.com/github/code…

大数据系列——什么是Flink?Flink有什么用途?

目录 一、基本概念 批与流 数据可以作为无界流或有界流处理 二、什么是Flink&#xff1f; 三、Flink有什么用途&#xff1f; 四、适用场景 五、flink事件驱动 六、flink拥有分层API flink sql 七、fllink企业级使用 一、基本概念 批与流 批处理的特点是有界、持久、大…

被误认为是外国人开发的4款软件,功能强大到离谱,且用且珍惜

国外的月亮不一定比国内圆&#xff0c;随着国内互联网飞速发展&#xff0c;国内研发出许多实用又良心的软件&#xff0c;由于偏见&#xff0c;功能强大的它们却被误认为是外国佬研发的。 1、Foxit PDF用系统自带的Adobe实在难用&#xff0c;Foxit这款PDF阅读器实在太强大&#…

unity使用RenderTexture可以渲染粒子特效

一&#xff0c;使用UIRawImage,创建材质球&#xff0c;把Shader给材质球&#xff0c;放到RawImage的Material上&#xff0c; // Upgrade NOTE: replaced mul(UNITY_MATRIX_MVP,*) with UnityObjectToClipPos(*)Shader "UI/Default No-Alpha" {Properties{[PerRende…

基于文本和图像的网络舆情分析方法研究

基于文本和图像的网络舆情分析方法研究 一、舆情分析技术 &#xff08;1&#xff09;舆情数据采集与提取技术&#xff1b; &#xff08;2&#xff09;自动文摘技术&#xff1b; &#xff08;3&#xff09;事件发现与追踪技术&#xff1b; &#xff08;4&#xff09;舆情情感分…

【虚幻引擎UE】UE5 模型描边的三个方法

一、后期处理法 1、创建描边材质&#xff0c;方法很多种&#xff0c;主要有设置深度、法线描边等 可以参考现有文章制作或直接下载材质资源使用。 参考文章&#xff1a; 1、【UE4】几种后处理描边的方法&#xff0c;效果及效率 2、UE4之物体描边 3、【UE4_001】后期处理轮廓…

第002课 - 项目整体效果展示

文章目录 基础篇高级篇流量控制:alibaba sentinel注册中心链路追踪高可用集群篇CICD这个章节是进行项目效果的演示。 基础篇 第一个就是基础篇。 这是我们的后台管理系统。 围绕电商的管理系统做一个整套的增删改查逻辑。 这个商品系统都会教给大家来编写的。 这个是使用前…

网站报错:PHP Fatal error: Allowed memory size of 134217728 bytes exhausted的处理方法

原因分析 内存已耗尽&#xff0c;这关系到PHP的memory_limit的设置问题&#xff0c;根据自己的需要及参考本机的内存大小修改php内存限制。 解决方案 1、修改php.ini &#xff08;改配置&#xff09; memory_limit 128 这种方法需要重启服务器&#xff0c;很显然&#xff0c…

向Linux内核添加驱动的步骤详解

1、获取驱动源码 (1)驱动源码一般都是从设备厂商处获取&#xff1b; (2)设备厂商给的驱动源码大体上是没有问题的&#xff0c;能加载但是效果不一定好&#xff0c;需要根据自己的板子进行适配&#xff1b; 2、驱动在内核中的两种形式 (1)直接编译进内核&#xff1a;内核启动时自…

ubuntu下编译opencv

目录 1. 下载opencv和opencv-contrib 2. 安装依赖 3. cmake 4. make 5. 安装 6. 配置opencv的路径 7. 测试 后续 1. 下载opencv和opencv-contrib https://github.com/opencv/opencv/archive/refs/tags/4.6.0.zip https://github.com/opencv/opencv_contrib/archive/re…