<贪心算法>

news2025/5/14 4:00:15

前言:在主包还没有接触算法的时候,就常听人提起“贪心”,当时是layman,根本不知道说的是什么,以为很难呢,但去了解一下,发现也不过如此嘛(bushi),还以为是什么高级东西呢(开个玩笑,本蒟蒻只会点基础的)。本篇以一道简单题引入,不懂算法也会哦

题目:拼数  NC16783

思路: 本蒟蒻开始想当然了,以为直接以字符串从大到小排拼接起来就好了(有没有人和我一样),但没考虑全面。如特殊例子,A="321",B="32",若只按字符串大小拼接,则答案为“32132”,但正确答案应该是“32321”,所以还应该比较拼接后的大小,返回大的那一个

错误代码:

#include <iostream>
#include <algorithm>
using namespace std;
bool cmp(string a,string b){
    return a>b;
}
int main(){
    int n,i;
    string s[25];
    cin>>n;
    for(i=0;i<n;i++) cin>>s[i];
    sort(s,s+n,cmp);
    for(i=0;i<n;i++){
        cout<<s[i];
    }
    return 0;
}

正确代码:

#include <iostream>
#include <algorithm>
using namespace std;
bool cmp(string a,string b){
    return a+b>b+a;
}
int main(){
    int n,i;
    string s[25];
    cin>>n;
    for(i=0;i<n;i++) cin>>s[i];
    sort(s,s+n,cmp);
    for(i=0;i<n;i++){
        cout<<s[i];
    }
    return 0;
}

再来做一题感受一下吧

题目:华华听月月唱歌 NC23036

代码:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
vector<pair<int,int> >pd;
int main(){
	int n,m,l,r,i,c=1;
	cin>>n>>m;
	for(i=0;i<m;i++){
		cin>>l>>r;
		pd.push_back({l,r});
	}
	sort(pd.begin(),pd.end());     //pair类型先按第一个元素排序,相等再按第二个
	if(pd[0].first!=1){  //若开头不是1,肯定不能修复
		cout<<-1;
		return 0;
	}
	l=1,r=1;
	for(i=0;i<m;i++){
		if(pd[i].first<=l){     //同一片段选终点最大的
			r=max(r,pd[i].second);
		}else{      //新的片段
			if(pd[i].first>r+1){   //不连续
				cout<<-1;
				return 0;
			}
			c++;
			l=r+1;  //新的l为上一段终点+1
			r=max(r,pd[i].second);   //更新r 
		}
		if(r>=n){     //!!!及时结束!!!
			break;
		}
	} 
	if(r<n){
		cout<<-1;
		return 0;
	}
	cout<<c;
	return 0;
}

贪心算法是一种在每一步选择中都采取当前状态下最优(如最小,最大…)的选择,从而希望导致结果是全局最优的算法,所以常常需要对元素进行排序(之前的最小生成树,Dijkstra算法求最短路径等就有利用)。

但贪心算法并不是对所有问题都适用。它只能在满足贪心选择性质和最优子结构性质的问题中有效。贪心选择性质是指问题的全局最优解可以通过局部最优解来得到;最优子结构是指问题的最优解包含其子问题的最优解。


还有和上面一题相似的活动安排问题也是贪心的经典题,但我暂时找不到合适的题目出处,就用【算法设计与分析】活动安排问题(动态规划和贪心算法)_活动安排 动态规划-CSDN博客这篇博客的截图了(正常应该会要我们自己排序)

问题描述:给定n个活动活动,每个活动都有一个开始时间和结束时间。目标是在一个空间内安排尽可能多的活动。

思路:将活动按结束时间从小到大排序,每次选择结束时间最早且与已安排的活动不冲突的活动(关键)

代码:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
bool cmp(pair<int,int>a,pair<int,int>b){
	return a.second<b.second;
}
int main(){
	int n,i,start,end;
	cin>>n;
	vector<pair<int,int> >events;
	for(i=0;i<n;i++){
		cin>>start>>end;
		events.push_back({start,end});
	}
	sort(events.begin(),events.end(),cmp);
	int count=0,endt=0;
	for(auto event:events){      //基于范围的for循环,event遍历events容器中的每个元素(C++11及以后的保准)
		if(event.first>=endt){   //与已安排活动不冲突
			count++;
			endt=event.second;
		}
	}
	cout<<count;
	return 0;
}

本篇我的第11行代码蓝色dev-c++是运行不了的,在文末我会推荐一款"新的"傻瓜集成开发环境。

 题目:排座椅  NC16618

 这怎么贪呢?有点想不出啊

思路:要使答案最优,就要让K条横线和L条竖线穿过尽可能多的会交头接耳的两个人。所以分别记录每行每列所能分割的学生对数,再从大到小排序即可。

代码:

#include<iostream>
#include<algorithm>
using namespace std;
struct jl{
	int index,num;
}row[1010],col[1010];    //row[index]存储index行能分割的学生对数
bool cmp1(jl a,jl b){
	return a.num>b.num;  //按分割数从大到小排
}
bool cmp2(jl a,jl b){
	return a.index<b.index;
}
int main(){
	int m,n,k,l,d;
	cin>>m>>n>>k>>l>>d;
	int x,y,p,q,i;
	for(i=0;i<d;i++){
		cin>>x>>y>>p>>q;
		if(x==p){        //行号相等,列计数+1
			y=min(y,q);
			col[y].index=y;
			col[y].num++;
		}else if(y==q){
			x=min(x,p);
			row[x].index=x;
			row[x].num++;
		}
	}
	sort(row,row+m+1,cmp1);
	sort(col,col+n+1,cmp1);
	sort(row,row+k,cmp2);        //再将k行按序号从小到大输出
	sort(col,col+l,cmp2);
	for(i=0;i<k;i++) cout<<row[i].index<<" ";
	cout<<endl;
	for(i=0;i<l;i++) cout<<col[i].index<<" ";
	return 0;
}

题目:矩阵消除游戏  NC200190

这题就有些复杂了,选的行会影响到剩下列和的值,只考虑选每一次的最优解,会影响到下一次的选择吧!我不是球球,帮不了呀。看了大佬的题解,我佬果然还是我佬

思路过程: 如果只按行选,或者只按列选,直接贪心就可以了。但没有交叉(只选行或只选列)只能保证选的数字最多,未必的最大的,例如:3  3  2   【【1  5  1】【5 5 5】【1 5 1】】。每次选最优解也不一定最大,例如:4 4 3【【 1 1 9 3】【 1 8 10 8】【1 2 7 2】【 1 2 2 2】】,先选第三列,然后选第二行和第四列,但是直接选选第二三四列结果更大。有点上一篇背包的意思,给你一个体积为V的背包,再给你若干件体积不同的物品,希望选一些物品尽量装满,你会上来就选择最大的吗?     

思路:   n,m都小于15,说明本题可以暴力枚举 。我们采用先枚举后贪心的方法, 先枚举所有行的情况(二进制枚举法),再贪心选择最多的前几列

二进制枚举——当每个个体都面对两种选择的时候,可以用一个01串表示,对于本题,每一行有选和不选两种可能,假设有5行的话,我们就可以用一个长度为5的01串来表示,0表示不选,1表示选,如:01001 表明选第2和第5行。二进制1的数量就是选取行的数量,二进制1的位置就是选取行的位置。长度为n的01串的十进制范围在0~2^n-1

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,k;
int a[20][20];
long long row[20],col[20];  //row[i]存储第i行数据的和
int flag[20];                   //标记所选行
int count(int x){
	int c=0;
	for(int i=0;i<n;i++){
		if(x&(1<<i)){           //位运算在A+B problem那一篇有介绍,大家也回顾一下
			flag[i+1]=1;        //当然也可以直接二进制转换
			c++;
		}else{
			flag[i+1]=0;
		}
	}
	return c;
}
bool cmp(long long a,long long b){
	return a>b;
}
int main(){
	int i,j;
	long long sum=0;           //该养成long long潜意识了
	cin>>n>>m>>k;
	for(i=1;i<=n;i++){
		for(j=1;j<=m;j++){
			cin>>a[i][j];
			row[i]+=a[i][j];
			sum+=a[i][j];
		}
	}
	if(k>=n||k>=m){          //k>=行或列,则可以选择全部
		cout<<sum;
		return 0;
	}
	sum=0;
	for(i=0;i<(1<<n);i++){   //遍历2^n种行选择情况
		long long ans=0;        //存储该种情况的最大分数
		int numh=count(i);      //该情况所选行数
		int numl=k-numh;
		if(numl>m||numl<0){     //这种情况不存在
			continue;     
		} 
		for(j=1;j<=n;j++){
			if(flag[j]){
				ans+=row[j];
			}
		}
		memset(col,0,sizeof(col));
		for(j=1;j<=m;j++){      //计算选完行后的列和
			for(int h=1;h<=n;h++){
				if(!flag[h]){
					col[j]+=a[h][j];
				}
			}
		}
		sort(col+1,col+m+1,cmp);  
		for(j=1;j<=numl;j++){            
			ans+=col[j];  //从最后面(最大)开始加
		}
		sum=max(sum,ans);
	}
	cout<<sum;
	return 0;
}

下一题是一道提高组的题,本来觉得不好想,不分享算了。但它由特殊到一般推公式的思想还挺牛波一的,还是简单分析下思路,代码就贴我以前写的了

题目:国王的游戏  NC16561

思路: 以下图片截自一位牛客博主savage,据图,所以我们只需将ai​×bi从小到大排序,便能获得最多大臣的最小值。最后注意数据大小,利用之前学的高精度

 代码:

#include<iostream>
using namespace std;
string cheng(string a,string b){
	int lena=a.size(),lenb=b.size(),lenc=lena+lenb;
	string c(lenc,'0');
	int i,j;
	for(i=lena-1;i>=0;i--){
		for(j=lenb-1;j>=0;j--){
			int x=a[i]-'0',y=b[j]-'0';
			int num=x*y+c[i+j+1]-'0';
			c[i+j+1]=num%10+'0';
			c[i+j]+=num/10;
		}
	}
	c.erase(0,c.find_first_not_of('0'));
	return c;
}
void chu(string s,int b){
	int a[1000000],ans[100000];
	int len=s.size(),i,res=0;
	for(i=0;i<len;i++){
		a[i]=s[i]-'0';
	}
	for(i=0;i<len;i++){
		res=res*10+a[i];
		ans[i]=res/b;
		res%=b;
	}
	i=0;
	while(ans[i]==0){
		i++;
	}
	for(int j=i;j<len;j++){
		cout<<ans[j];
	}
}
int main(){
	int n,a,b,mx=0;
	cin>>n>>a>>b;
	string c=to_string(a);
	while(n--){
		cin>>a>>b;
		c=cheng(c,to_string(a));
		mx=max(mx,a*b);
	} 
	chu(c,mx); 
	return 0;
}  

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

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

相关文章

基于银河麒麟桌面服务器操作系统的 DeepSeek本地化部署方法【详细自用版】

一、3种方式使用DeepSeek 1.本地部署 服务器操作系统环境进行,具体流程如下(桌面环境步骤相同): 本例所使用银河麒麟高级服务器操作系统版本信息: (1)安装ollama 方式一:按照ollama官网的下载指南,执行如下命令: curl -fsSL https://ollama.com/install.sh | sh方…

「2025最新版React+Ant Design+Router+TailwindCss全栈攻略:从零到实战,打造高颜值企业级应用

一站式掌握最新技术栈&#xff01;手把手教你配置路由、集成UI组件库、高效开发秘籍大公开 ReactAntrouteraxiosmocktailwind css等组合安装使用教程 官网&#xff1a;React Native 中文网 使用React来编写原生应用的框架 一&#xff0c;安装 npx create-react-app my-app …

Ubuntu 24.04.2 LTS 系统安装python,创建虚拟环境

在 Ubuntu 24.04.2 LTS 系统中&#xff0c;系统本身自带了 Python 3&#xff0c;不过你还是可以按照下面的步骤来安装和配置 Python 环境。 1. 检查系统自带的 Python 版本 在终端中输入以下命令查看系统自带的 Python 版本&#xff1a; python3 --version如果显示了 Python…

redis7.0搭建redis-cluster集群部署实战

环境 基于3台centos服务 host节点1端口节点2端口master70007001slave170007001slave270007001 安装redis&#xff0c;以及环境准备 安装可以参考https://blog.csdn.net/tao1992/article/details/132614567 安装路径设置了/usr/local/redis 分别在3台服务器上执行 #配置文…

CMake学习--如何在CMake中编译静态库、动态库并在主程序中调用

目录 一、背景知识二、使用方法&#xff08;一&#xff09;编译静态库&#xff08;二&#xff09;编译动态库&#xff08;三&#xff09;在主程序中调用库 三、总结 一、背景知识 在C/C开发中&#xff0c;库&#xff08;Library&#xff09;是预先编译好的代码集合&#xff0c…

安美数字酒店宽带运营系统存在SQL注入漏洞

免责声明&#xff1a;本号提供的网络安全信息仅供参考&#xff0c;不构成专业建议。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权&#xff0c;请及时与我联系&#xff0c;我将尽快处理并删除相关内容。 漏洞描述 安美数字酒店宽带运营系统的lang…

ubuntu18 server版花屏问题

新搞了一台dellT150的塔式服务器&#xff0c;装的ubuntu18 server版。 开机后遇到花屏&#xff0c;或者卡在开机界面的问题&#xff0c;和售后技术沟通这个情况是ubuntu自带的显卡驱动包兼容问题。需要做如下设置&#xff1a; 解决&#xff1a; 1.开机&#xff0c;连续按下e…

基于神经网络的肾脏疾病预测模型

构建一个基于神经网络的肾脏疾病预测模型 1. 数据预处理 ​加载数据&#xff1a;读取 kidney_disease.csv 文件&#xff0c;加载患者医疗数据。​删除冗余特征&#xff1a;移除与预测目标无关的列&#xff08;如 al, su 等&#xff09;&#xff0c;保留关键特征&#xff08;如…

I/O多路复用 + Reactor和Proactor + 一致性哈希

网络系统 1. I/O多路复用1&#xff09;原始Socket模型通信方式2&#xff09;多进程模型3&#xff09;多线程模型4&#xff09;I/O多路复用select/pollepoll边缘触发和水平触发 2. Reactor和Proactor1&#xff09;Reactor模式2&#xff09;Reactor模式四种方案3&#xff09;单Re…

解决小程序video控件在真机和上线后黑屏不播放问题

小程序上线后&#xff0c;mp4格式的视频无法点击是黑屏&#xff0c;但是测试得时候在微信开发者工具中能够打开正常播放 原因&#xff1a;编码格式不能是vp9 微信开发者工具本地设置中把这个打开勾选。 排查&#xff1a;可以换一个视频尝试能不能真机播放&#xff0c;如果能&a…

java项目分享-分布式电商项目附软件链接

今天来分享一下github上最热门的开源电商项目安装部署&#xff0c;star 12.2k&#xff0c;自行安装部署历时两天&#xff0c;看了这篇文章快的话半天搞定&#xff01;该踩的坑都踩完了&#xff0c;软件也打包好了就差喂嘴里。 项目简介 mall-swarm是一套微服务商城系统&#xf…

【LVS】负载均衡群集部署(DR模式)

部署前IP分配 DR服务器&#xff1a;192.168.166.101 vip&#xff1a;192.168.166.100 Web服务器1&#xff1a;192.168.166.104 vip&#xff1a;192.168.166.100 Web服务器2&#xff1a;192.168.166.107 vip&#xff1a;192.168.166.100 NFS服务器&#xff1a;192.168.166.108 …

链表的操作-反转链表

链表 160相交链表 代码 class Solution { public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {ListNode* h1headA;ListNode* h2headB;while(h1&&h2){if(h1!h2){h1h1->next;h2h2->next;}else{return h1;}}if(h1nullptr){h1headB;}else{h…

Linux安装Cmake (Centos 7.9)

cmake安装 这个虽然已经更新到了4.0.0版本了&#xff0c;但是我们要用3.5版本的&#xff0c;因为这个比较稳定 官方地址&#xff1a;https://github.com/Kitware/CMake/releases/tag/v3.5.0&#xff0c;选择那个cmake-3.5.0-Linux-x86_64.tar.gz下载&#xff0c; 首先解压文…

Node.js v22.14.0 多平台安装指南:Windows、Linux 和 macOS 详细教程

Node.js作为现代Web开发的基石&#xff0c;持续为开发者带来性能提升和新特性支持。本文将详细介绍在Windows、macOS和Linux系统上安装最新Node.js的多种方法&#xff0c;助您快速搭建高效的JavaScript开发环境。 &#x1f4e6; 当前最新版本 截至2025年4月&#xff0c;Node.…

Netty源码—10.Netty工具之时间轮一

大纲 1.什么是时间轮 2.HashedWheelTimer是什么 3.HashedWheelTimer的使用 4.HashedWheelTimer的运行流程 5.HashedWheelTimer的核心字段 6.HashedWheelTimer的构造方法 7.HashedWheelTimer添加任务和执行任务 8.HashedWheelTimer的完整源码 9.HashedWheelTimer的总结…

鸿蒙项目笔记(1)

一、核心内容-商城 1、装饰器的拓展使用&#xff0c;基础组件的熟悉。 2、引入基础动画实战&#xff0c;页面属性动画、页面跳转动画、自定义页面翻页等。 3、一次开发&#xff0c;多端部署。 4、本地数据库实战&#xff0c;涉及多种本地数据存储方式。 5、路由导航&#…

*快排延伸-自省排序

此节是学有余力的人去看&#xff0c;如果没时间&#xff0c;不看也没关系&#xff0c;只要知道代码就可以了&#xff01; 自省排序的思路是自我侦测和反省&#xff0c;快速排序如果递归深度太深&#xff0c;其算法的效率可能被大幅度削弱&#xff0c;这就需要借助其他的算法进…

三.微服务架构中的精妙设计:服务注册/服务发现-Eureka

一.使用注册中心背景 1.1服务远程调用问题 服务之间远程调⽤时, 我们的URL是写死的 String url "http://127.0.0.1:9090/product/" orderInfo.getProductId(); 缺点&#xff1a; 当更换机器, 或者新增机器时, 这个URL就需要跟着变更, 就需要去通知所有的相关服…

python-leetcode 63.搜索二维矩阵

题目&#xff1a; 给一个满足两条属性的m*n的整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列 每行的第一个整数大于前一行的最后一个整数 给一个整数target,如果target在矩阵中&#xff0c;返回true,否则返回false 方法一&#xff1a;两次二分查找 由于每…