C++贪心算法

目录

一,定义

二,特点

三,使用

四,步骤:

1.将问题分解为若干个问题

2.找出适合该题目的贪心策略

3.求解每个子问题的最优解

4.组合局部最优解

五,例题:

1,最优装载

题目分析(个人想法):

详见代码:

2,删数问题

题目分析:

ACcode


一,定义

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

二,特点

贪心算法的特点是在每一步都做出局部最优的选择,以期达到全局最优解,但并不保证能得到全局最优解。【字面意思就是++每一步只看当下而不管未来++。保证当下是最优解】

三,使用

因为贪心算法的特性,所以很多算法也运用到了贪心的思想

例如之前说过的,求最短路径:dijkstra

求最小生成树的:Kruskal prim

都是选择当前点能到达的最长(最短)的边权来进行选择,所以有些时候不是最优解。

四,步骤:

1.将问题分解为若干个问题

2.找出适合该题目的贪心策略

3.求解每个子问题的最优解

4.组合局部最优解

五,例题:

1,最优装载

题目分析(个人想法):

由题目描述可以知道,我们要寻找总价值最大的金币总和。首先就需要用价值/总质量 ,得出每单位质量下每项金币的价值。根据生活实际的惯例,在有限的空间里要尽可能地多地拿价值更高的金币,这样才能使总价值最高。因为金币可以切割,当背包空间不足时,所以我们就可以剩余的空间乘上当前价值最高的金币的单位价值,最后将背包空间塞满,所得的物品总价值最大。

详见代码:

cpp 复制代码
#include<bits/stdc++.h>//万能头文件。!
using namespace std;
struct node{//使用一个结构体来记录每种物品的各项信息
	double x,y,w;//总质量,总价值,每单位质量的价值
	bool operator<(const node &p) const{//重载一下运算符方便将价值排序
		return w>p.w;
	}
}a[105];
long long read() {//日常快读压时间
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9') {
		if(c=='-') f=-1;
		c=getchar();
	}
	while(c>='0'&&c<='9') {
		x=x*10+c-'0';
		c=getchar();
	}
	return x*f;
}
int main(){
	int n,m;//题目要求的n和m
	n=read();
	m=read();
	for(int i=1;i<=n;i++){
	    cin>>a[i].x>>a[i].y;//输入价值和质量
	    a[i].w=a[i].y/a[i].x;//运用公式计算出金币的单位价值
	}
	sort(a+1,a+n+1);//简单给结构体排一下序
	double ans=0;//建立一个变量来记录背包里的金币价值
	for(int i=1;m>0,i<=n;i++){
		if(m>=a[i].x)ans+=a[i].y,m=m-a[i].x;//如果背包剩余空间大于目前价值最大的金币质量,直接全部放入,剩余空间减小。
		else ans+=m*a[i].w,m=0;//背包空间有但还是不足的话,就用剩余空间乘上目前价值最高的金币的单位质量的价值
	}
	
	cout<<fixed<<setprecision(2);//按照题目要求保留两位小数
	cout<<ans;//输出背包价值
} 

2,删数问题

题目分析:

根据基本数学知识可得:当两个数数位相同的时候,高位越小,数越小,所以优先考虑第i位>i+1位的第i位删除,当删干净了,就只剩0。因为是高精度数,所以使用string字符串结构更优。

ACcode

cpp 复制代码
#include<iostream>//普通头文件
using namespace std;
int main() {
    string s;
	int k;
	cin>>s>>k;//先将被处理的数和处理的次数输入,
    while (k) {//重复k次操作。
    	int i;
        for (i=0;i<s.size()-1&&s[i]<=s[i+1];i++);
        s.erase(i,1);
        k--;
    }
    if (s.empty()) {
        cout << 0 << endl;
        return 0;
    }
    int i=0;
    for (i=0;i<s.size()-1;) {
        if (s[i] =='0') i++;
        else break;
    }
    for(i;i<=s.size();i++){
    	cout<<s[i];
	}
    return 0;
}
相关推荐
神仙别闹1 分钟前
基于C#和Sql Server 2008实现的(WinForm)订单生成系统
开发语言·c#
XINGTECODE2 分钟前
海盗王集成网关和商城服务端功能golang版
开发语言·后端·golang
我们的五年12 分钟前
【Linux课程学习】:进程程序替换,execl,execv,execlp,execvp,execve,execle,execvpe函数
linux·c++·学习
zwjapple19 分钟前
typescript里面正则的使用
开发语言·javascript·正则表达式
小五Five20 分钟前
TypeScript项目中Axios的封装
开发语言·前端·javascript
前端每日三省22 分钟前
面试题-TS(八):什么是装饰器(decorators)?如何在 TypeScript 中使用它们?
开发语言·前端·javascript
凡人的AI工具箱35 分钟前
15分钟学 Go 第 60 天 :综合项目展示 - 构建微服务电商平台(完整示例25000字)
开发语言·后端·微服务·架构·golang
做人不要太理性38 分钟前
【C++】深入哈希表核心:从改造到封装,解锁 unordered_set 与 unordered_map 的终极奥义!
c++·哈希算法·散列表·unordered_map·unordered_set
程序员-King.1 小时前
2、桥接模式
c++·桥接模式
chnming19871 小时前
STL关联式容器之map
开发语言·c++