关于 贪心 算法

所谓贪心: 就是只管当下的最优解。

下面看 一个例题:

此例题来自洛谷 P2859 [USACO06FEB]Stall Reservations S;

下面看题目:

 解题思路:

每头奶牛的开始与结束时间 可以看成一个线段;求解当下线段重合部分的最大值;

#include<bits/stdc++.h>
using namespace std;

struct COW {
	int begin,end;
	int id;         // 为每一个奶牛编号,方便最后被打乱顺序之后恢复原样
	int used_in_which;  //奶牛用过的牛棚的编号
}cow[50004];

bool cmp(COW a,COW b){
	return a.begin < b.begin;
}
bool cmp1(COW a, COW b) {
	return a.id < b.id;
}
priority_queue <pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>> >q;
// 前置知识:: pari的比较,先比较第一个元素,第一个相等比较第二个.
// 优先队列 : 先以结束时间进行比较 结束时间小的排前面; 如果结束时间 一样 比较 围栏的数量 围栏小的 排前面.

int main() {
	int n = 0;
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%d%d", &cow[i].begin, &cow[i].end);
		cow[i].id = i ;// 为每一个奶牛编号,方便最后被打乱顺序之后恢复原样.
	}
	sort(cow, cow + n, cmp);  // 进行排序 : 以开始时间开始排升序.
	cow[0].used_in_which = 1;     // 第一头奶牛直接 开一个 围栏.
	int tot = 1;				  // 围栏的总数.
	q.push(make_pair(cow[0].end, tot));   // 输入第一头奶牛的结束时间.
	for (int i = 1; i < n; i++) {
		int x = q.top().first;    // 取优先(升序)队列的 首元素.
		int cur_id = q.top().second; // 取 首奶牛的 栅栏序号 
		if (cow[i].begin > x) {   // 如果 第 i 头奶牛的 开始时间 大于 排在 优先队列首元素的结束时间 那么就可以进行无缝衔接,直接继承.
			q.pop();			  // 进来之后 首元素的用处就没有了 进行 Pop.
			q.push(make_pair(cow[i].end,cur_id));   // 推入新的奶牛的 结束时间, 以及栅栏序号.
			cow[i].used_in_which = cur_id; // ** 记录第 i 头 奶牛的栅栏编号
		}
		else {
			tot++;			     // 如果 第 i 头 奶牛的开始时间 小于 排在优先队列首元素的结束时间 那么 需要新开一个栅栏.
			cow[i].used_in_which = tot;  // 第 i 头 奶牛的栅栏位置 就为 新的 tot.
			q.push(make_pair(cow[i].end,tot));  // 推入新的奶牛的 结束时间, 以及栅栏序号.
		}
	}
	// 接下来进行打印;
	printf("%d\n", tot);
	sort(cow, cow + n, cmp1);
	for (int i = 0; i < n; i++) {
		printf("%d\n", cow[i].used_in_which);
	}

	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是 Python 语言实现的一个简单的贪心算法程序,用于解决经典的背包问题: ```python def greedy_knapsack(weights, values, capacity): """ 贪心算法求解背包问题 :param weights: 物品重量列表 :param values: 物品价值列表 :param capacity: 背包容量 :return: 背包能够装下的最大价值 """ n = len(weights) # 计算物品单位价值 unit_values = [v / w for v, w in zip(values, weights)] # 按照单位价值从大到小排序 sorted_indices = sorted(range(n), key=lambda i: unit_values[i], reverse=True) # 初始化背包当前容量和总价值 curr_capacity = 0 total_value = 0 # 依次选择单位价值最大的物品放入背包中 for i in sorted_indices: if curr_capacity + weights[i] <= capacity: curr_capacity += weights[i] total_value += values[i] else: # 当前物品无法完整放入背包,只能放入一部分 remaining_capacity = capacity - curr_capacity total_value += remaining_capacity * unit_values[i] break return total_value ``` 该程序接受三个参数:物品重量列表 `weights`、物品价值列表 `values` 和背包容量 `capacity`,返回背包能够装下的最大价值。程序先计算每个物品的单位价值(即价值重量比),然后按照单位价值从大到小排序,依次选择单位价值最大的物品放入背包中,直到背包不能再装下任何一个物品为止。如果当前物品无法完整放入背包,只能放入一部分,则只取部分即可。 注意,这只是一个简单的贪心算法程序,不一定能够求解所有背包问题,可能会存在特殊情况下的错误解。如果需要求解更复杂的背包问题,可能需要使用更高级的算法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值