贪心算法[1]

首先用最最最经典的部分背包问题来引入贪心的思想。

由题意可知我们需要挑选出价值最大的物品放入背包,价值即单位价值。

我们需要计算出每一堆金币中单位价值。金币的属性涉及两个特征,重量和价值。

所以我们使用结构体。

上代码。

cpp 复制代码
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
struct Item {
    int c, w;
};//定义结构体,c代表价值,w代表重量
Item item[1010];//创建结构体变量
bool cmp(Item a, Item b){//定义排序方式
    return a.w * b.c > b.w * a.c;//单价的转换形式
}//排序函数,说白了就是比性价比
int main() {
    int N, V;
    cin >> N >> V;
    for (int i = 1; i <= N; i++) {
        cin >> item[i].c >> item[i].w;
    }
    sort(item + 1, item + N + 1, cmp);//输入后排序
    double ans = 0;
    for(int i=1; i<=N; i++){
        if(V <= item[i].c){
            ans += (double)item[i].w / item[i].c * V;//double强转
            V = 0;
            break;
        }
        else{
            ans += item[i].w;
            V -= item[i].c;
        }
    }
    printf("%.2lf", ans);
    return 0;
}

第二种写法

cpp 复制代码
class Item {//定义一个类里面包含价值和重量两个参数,以方便创建vector数组
public:
	int w, v;//变量
	Item(int w, int v) :w(w), v(v) {//列表初始化

	}
	
};
double solve(vector<int>& wei, vector<int>& val,int t)
{
	vector<Item>ans;//声明类型为Item的vector数组,每一个元素包含两个变量
	for (int i = 0; i < wei.size(); i++)
	{
		ans.push_back(Item(wei[i], val[i]));//将价值和重量填入创建的Item类型数组
	}
	sort(ans.begin(), ans.end(), [](Item& a, Item& b) {return(double)a.v / a.w > (double)b.v / b.w; });//对vector数组进行排序,lamba表达式【】为定义排序的格式,这里也可以定义一个bool函数来实现排序的方式
	double res = 0;
	for (auto& items : ans)//遍历
	{
		if (items.w <= t)//如果第一堆金币总重量小于背包重量全部放入
		{
			res += items.v;
			t -= items.w;
		}
		else {
			res +=(double)items.v / items.w * t;//将剩余的重量用最大的价值单价填入
			break;
		}
	}
	return res;
}

int main()
{
	int n, t,w,v;
	cin >> n >> t;
	vector<int>wei;//创建重量数组
	vector<int>val;//创建价值数组
	for (int i = 0; i < n; i++)
	{
		cin >> w >> v;
		wei.push_back(w);
		val.push_back(v);
	}

	double ans = solve(wei, val,t);
	printf("%.2lf", ans);
}

这一题选自洛谷p1223题,根据题意我们可以知道要想得到最短的等待时间得先让排队时间少的先接水。下面介绍两种方法进行解决。

由于题目既要有接水时间又要有序号且这两个元素是对应同一个人,所以我们第一种方法使用结构体。

上代码。

cpp 复制代码
#include <iostream>
#include <vector>
#include <algorithm>
#include<cstdio.h>

using namespace std;
struct human {
    int b, num;//输出的两个变量有联系,用结构体
};
bool cmp(human a, human x)//定义比较的方式
{
    return a.b < x.b;
}
int main()
{
    struct human ans[1001];
    int n, i, j;
    double time = 0;
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> ans[i].b;//每个人的时间
        ans[i].num = i;//每个人对应的序号
    }
    sort(ans + 1, ans + n + 1, cmp);
    for (int i = 1; i <= n; i++)
    {
        cout << ans[i].num << " ";
    }
    cout << endl;
    for (j = n - 1; j >= 1; j--)
    {
        i = n - j;//此时的总人数
        time += ans[i].b * j;//当前人的等待时间要乘以此时的总人数
    }
   printf("%.2lf",time);
   return 0;
}

第二种方法,不使用结构体,使用vector+pair。

cpp 复制代码
#include <iostream>//洛谷p1223
#include <vector>
#include <algorithm>

using namespace std;
int main() {
    int n;
    double sum = 0;
    cin >> n;
    vector<pair<int, int>> a(n);//既要记录每个人的序号也要记录每个人的时间,定义vector的元素类型为pair
    for (int i = 0; i < n; i++) {
        cin >> a[i].first;//第一个为时间,调用每一个为pair类型元素的first
        a[i].second = i + 1;//第二个为序号,调用每一个为pair类型元素的second
    }
    sort(a.begin(), a.end());//排序,升序

    for (int i = 0; i < n; i++) {
        sum += a[i].first * (n - i - 1);//先排上的人后面所有人都要等待
        cout << a[i].second << " ";
    }

    printf("\n%.2f", sum / n);

    return 0;
}
相关推荐
钢铁男儿13 分钟前
Halcon支持向量机
算法·机器学习·支持向量机
**K27 分钟前
C++ 智能指针使用不当导致内存泄漏问题
开发语言·c++·算法
Leo-Peng30 分钟前
辐射神经场算法——Instant-NGP / Mipi-NeRF 360 / 3D Gaussian Splatting
算法·nerf·3d gaussian
菌菌巧乐兹31 分钟前
C# 快速排序算法的详细讲解
算法·排序算法
TechQuester1 小时前
解决GPT-4o耗电难题!DeepMind新算法训练效率提升13倍,能耗降低10倍!
java·c++·人工智能·python·算法·chatgpt
XSTIT1 小时前
数据结构--二叉树相关题2(OJ)
数据结构·算法
观鉴词recommend1 小时前
【c++刷题笔记-动态规划】day32: 509. 斐波那契数 、 70. 爬楼梯 、 746. 使用最小花费爬楼梯
c++·笔记·算法·leetcode·动态规划
不决问春风1 小时前
102.二叉树的层序遍历——二叉树专题复习
java·算法·leetcode
郝YH是人间理想1 小时前
《算法笔记》总结No.3——排序
c语言·数据结构·c++·算法·排序算法·csp
a_golden_fish1 小时前
【做一道算一道】滑动窗口最大值
数据结构·算法