贪心算法——最优装载

装载问题1

问题描述:
某艘船的载重为C,现在给你n件物品,其中每件物品的重量是Wi,要求将尽可能多的物品装入船上。

输入
共n+1行
第一行n个物体、总重量C
后面n行,每行一个物体的重量wi)

输出
最多的物品的数量

样例输入

5 100
78
22
13
56
64

【样例输出】

3

策略分析:
由于题目要求装尽可能多的物品,那么很容易想到我们每次选择物品的时候应该选择尽可能轻的物品,这样才能保证选的尽可能多
因此
1、按照重量从小到大排序
2、循环进行遍历,查看当前重量是否能装下
3、能装下则计数器加1,否则退出循环

代码

#include <cstdio>
#include <algorithm>
#define MAXN 1000 + 10
int w[MAXN];
int main() {
	int n, C, now = 0, cnt = 0;
	scanf("%d%d", &n, &C);
	for(int i = 1; i <= n; i++)
		scanf("%d", &w[i]);
		
	std::sort(w+1, w+1+n);
	for(int i = 1; i <= n; i++) {
		if(now + w[i] <= C) { //如果能把能把第i个物品装入
			cnt++;
			now += w[i];
		}else 
			break;
	}
	printf("%d\n", cnt); 
	return 0;
} 

装载问题2

问题描述:
现有一个最大载重量为M的卡车和N种食品,每种食品都是散装的可拆分。已知第i种食品的最多拥有Wi公斤,其商品价值为Vi元/公斤,请确定一个装货方案,使得装入卡车中的所有物品总价值最大。

输入
n+1行
第一行:输入两个数分别是货车的最大载重量m(公斤)和货物的种类n
接下来n行:每行两个数,第一个是货物的拥有量wi公斤,货物的单价vi元/公斤
1≤m,n,wi,vi≤100

输出
一个数,最大价值

样例输入

5 100
78
22
13
56
64

样例输出

3

策略分析:
题目说明了每一种货物是可以拆分的,并且要求装入的总价值最大,那么很明显,我们应该计算出每种物品的单位价值,然后按照单位价值由大到小排序,依次装入
因此
1、读取数据时,就可以计算出单位价值
2、按照单位价值由大到小排序
3、循环遍历,能装下当下最大价值的就全部装,否则把剩余空间装满

代码

#include<cstdio>
#include<algorithm>
#define MAXN 100 + 15
struct food{
	int w;
	int v;
}s[MAXN]; 

bool cmp(food a, food b) { //按照价值从大到小排序
	return a.v > b.v;
}

int main() {
	int m, n, sum = 0, weight = 0, j = 1;
	scanf("%d%d", &m, &n);
	for(int i = 1; i <= n; i++) {
		scanf("%d %d", &s[i].w, &s[i].v);
	}
	std::sort(s+1, s+1+n, cmp);
	while(weight + s[j].w <= m) {	//如果当前种类的物品全部都能装进去
		weight += s[j].w;
		sum += s[j].w * s[j].v;
		j++;
	}
	sum += (m - weight) * s[j].v;	//把剩余空间装满
	printf("%d\n", sum);
	return 0;
}

小结:需要弄清楚怎么使得每一次的选择利益化最大(几乎所有贪心都要先排序)

猜你喜欢

转载自blog.csdn.net/weixin_43501684/article/details/89054522