#11-【贪心算法】合照

Description
歌手SJM到幼儿园跟小朋友玩,他到达的时候小朋友已经争着积木玩了。小朋友都想要更多的积木砌一个自己喜欢的图形,砌玩就可以和SJM合照。同时,SJM手上还有一些积木,他可以把手里的这些积木全部给一个小朋友,然后等该小朋友砌完后就可以收回所发的积木和该小朋友原先手里的积木。但SJM想知道他最多可以和多少个小朋友合照,你能帮助他吗?
Input
输入第一行包括两个正整数N和S,中间用空格隔开,其中1<=N<=1000,1<=S<=10000,表示一共有N位小朋友, SJM手上有S块积木。以下有N行,每行有两个正整数,a和b(1<=a<=10^5,1<=b<=10^9),表示每个小朋友手上有的积木数量和还需要的积木数量。

Output
输出SJM最多可以和多少个小朋友合照。

Sample Input
输入样例1:
2 2
1 4
2 1
输入样例2:
2 2
1 4
1 1
Sample Output
输出样例1:
2
输出样例2:
1
HINT
样例解释:

样例1:有2个小朋友,SJM手里一开始有2块积木,第1个小朋友手里有1块积木,他还需要4块积木,第2个小朋友手里有2块积木,他还需要1块积木,SJM可以先满足第2个小朋友的需求,即给第2个小朋友1块积木,这样第2个小朋友就可以砌完图形,然后把所有的积木给SJM,这样SJM就有4块积木,此时可以满足第1个的需求,所有可以和2个小朋友合照。

样例2:SJM一开始只能满足第2个小朋友的需求,然后积木数量变为3,还是不能满足第1个小朋友的需求,所以最多只能和1个小朋友合照。

ITS-EASY

#include <iostream>

#define SIZE 1001

using namespace std;

int a[SIZE], b[SIZE];
bool v[SIZE]; // 有没有弄(?)过

int main(int argc, char** argv)
{
	int n, s, i, t = 0;
	bool flag;
	
	cin >> n >> s;
	for (i = 1; i <= n; i++)
	{
		cin >> a[i] >> b[i]; // 读入数据
	}
	
	for ( ; ; )
	{
		flag = true;
		for (i = 1; i <= n; i++)
		{
			if ((!v[i]) && (s >= b[i])) // 若有一个符合条件
			{
				s += a[i];
				v[i] = true;
				t++;
				flag = false;
			}
		}
		if (flag) // 如果再没有则输出结果
		{
			cout << t << endl;
			return 0;
		}
	}
	
	return 0;
}

 

### 贪心算法解析及答案 贪心算法是一种通过一系列局部最优选择来构建整体最优解的策略[^3]。其核心思想在于每一步都选择当前状态下看起来最优的选择,而不考虑未来的可能影响。这种特性使得贪心算法在某些特定问题上能够高效地找到全局最优解,但并非所有问题都适用。 #### 1. 贪心算法的基本性质 贪心算法具有以下两个重要性质: - **贪心选择性质**:所求问题的整体最优解可以通过一系列局部最优的选择得到。这意味着每一步的选择仅依赖于当前状态,而不需要依赖未来的决策或子问题的解[^3]。 - **最优子结构性质**:一个问题的最优解包含其子问题的最优解。这一性质是动态规划和贪心算法共同具备的,但两者的实现方式不同[^3]。 #### 2. 贪心算法与动态规划的区别 尽管两者都依赖于最优子结构,但它们的实现方式存在显著差异: - 动态规划通常以自底向上的方式解决子问题,并存储中间结果以避免重复计算。 - 贪心算法则以自顶向下的方式迭代做出贪心选择,将问题逐步简化为更小规模的问题[^3]。 #### 3. 示例分析:找零问题 在引用中提到的一个典型例子是找零问题[^4]。假设需要找给顾客140元,且钱币面值有九种:100元、70元、50元、20元、10元、7元、5元、2元、1元。使用贪心算法时,每次都选择面值最大的钱币进行支付,直到满足总额。在这种情况下,贪心算法确实可以得到最优解,因为每次选择最大面值不会导致后续无法完成支付的情况。 #### 4. 最优装载问题代码解析 引用中提供了一段C语言代码,用于解决最优装载问题[^5]。该代码的核心逻辑是通过排序和贪心选择来确定装载顺序。以下是代码的关键部分及其解释: ```c #include <stdio.h> int a[100]; // 存储物品重量 int b[100]; // 存储物品价值 int n, k, sum = 1, flag = 0; int main() { scanf("%d", &n); // 输入物品数量 for (int i = 0; i < n; i++) { scanf("%d %d", &a[i], &b[i]); // 输入每个物品的重量和价值 } // 对物品按照重量升序排序,如果重量相同,则按价值降序排序 for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - i - 1; j++) { if (a[j] > a[j + 1]) { k = a[j]; a[j] = a[j + 1]; a[j + 1] = k; k = b[j]; b[j] = b[j + 1]; b[j + 1] = k; } if (a[j] == a[j + 1] && b[j] > b[j + 1]) { k = b[j]; b[j] = b[j + 1]; b[j + 1] = k; } } } // 使用贪心算法选择物品 for (int i = 1; i < n; i++) { if (a[i] >= b[flag]) { // 如果当前物品重量大于等于已选物品的最大价值 flag = i; sum++; } if (b[i] < b[flag]) { // 更新已选物品的最大价值 flag = i; } } printf("%d", sum); // 输出最大装载数量 } ``` 这段代码通过排序和贪心选择实现了最优装载问题的解决方案。它首先对物品按照重量和价值进行排序,然后依次选择符合条件的物品,确保最终装载的物品数量最大化。 #### 5. 总结 贪心算法适用于具有贪心选择性质和最优子结构的问题。通过一系列局部最优选择,它可以高效地找到全局最优解。然而,贪心算法并不总是适用,因此在实际应用中需要仔细验证其确性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值