概念
贪心算法是一种在每一步选择中都采取当前状态下最优的选择,希望通过一系列局部最优的选择,达到全局最优解的算法思想。简而言之,就是“每次都选最好的”。但它不一定能得到最终的最优解,因此适用性有限。例如,在找零钱问题中,我们通常会先用面值大的钱币,以减少钱币的数量。在实际应用中,我们需要区分问题是否适合用贪心算法解决,这通常需要通过数学证明来确认。此外,贪心算法的设计思路简洁,实现容易,是入门算法设计的良好选择。通过分析问题特点,合理设计贪心策略,我们可以有效地解决一系列优化问题。
1、贪心的小童-2909
题解:
程序目的是计算四堆胡萝卜中各自最重的一根的总重量。对于每一堆胡萝卜,首先记录下所有胡萝卜的重量,然后在该堆中找出最重的胡萝卜,最后将四堆中最重的胡萝卜重量求和。
步骤如下:
- 使用一个数组
a
来存储每堆胡萝卜的重量。 - 用循环读入每堆胡萝卜的数量
n
和对应的每个胡萝卜的重量,并存入数组a
。 - 在每次循环中,定义一个变量
t
用来暂存每堆胡萝卜中最重的重量。 - 通过内层循环,比较当前堆中的每个胡萝卜重量与
t
的大小,若当前胡萝卜重量更大,则更新t
。 - 每次外层循环结束后,将
t
(当前堆中最重的胡萝卜重量)累加到总和sum
上。 - 四次循环结束后,
sum
存储的就是四根最重胡萝卜的总重量。 - 输出
sum
。
代码中,数组 a
的大小被设置为1010,是为了确保能够存储最多1000个胡萝卜的重量。最后输出的 sum
就是所求的四根胡萝卜总重量的最大值。
#include <bits/stdc++.h>
using namespace std;
int a[1010],n,sum=0;
int main(){
for(int i=1;i<=4;i++){
cin>>n;
for(int j=1;j<=n;j++)
cin>>a[j];//输入n个胡萝卜的重量。
int t=0;//定义一个变量,存储每堆胡萝卜重量的最大值。
for(int j=1;j<=n;j++)
//胡萝卜的重量大于t,就更新t的值。求出每一堆的最优结果。
if(a[j]>t) t=a[j];
sum+=t;//累加每堆最重胡萝卜的重量,得到最终的最优结果。
}
cout<<sum<<endl;
return 0;
}
2、节省时间-2908
题解:
程序的目的是找出一种排队顺序,使得所有学生的答疑完成时间的平均值最小。根据调度理论中的SJF(Shortest Job First,最短作业优先)策略,我们知道最优的答疑顺序是按照答疑时间从短到长排序的。
以下是解题步骤:
- 读入学生数量
n
和每个学生的答疑时长存入数组a
。 - 对数组
a
进行升序排序,使得答疑时间短的学生排在前面。 - 初始化一个变量
s
来记录所有学生的答疑完成时间之和。 - 通过一个循环,计算每个学生的答疑完成时间,并累加到
s
上。对于第i
个学生,其答疑完成时间等于其自身的答疑时间a[i]
加上其前面所有学生答疑时间的总和。 - 在循环中,用
(n-i)*a[i]
计算当前学生答疑时,后面的学生需要等待的总时间,并将其加到s
。 - 循环结束后,
s
包含了所有学生的答疑完成时间之和。 - 使用
s
除以学生总数n
并保留两位小数输出,即为所求的最小平均答疑完成时间。
代码中使用了 fixed
和 setprecision(2)
来设置输出的浮点数精度为小数点后两位。最终输出的结果是所有学生的答疑完成时间的平均值。
#include <bits/stdc++.h>
using namespace std;
int a[1010],n;
int main(){
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
sort(a+1,a+n+1);//按照答疑时间升序排序
int s=0;
for(int i=1;i<=n;i++){
//第1个人的答疑时间是后面n-1个人的等待时间,第i个人的答疑时间是后面n-i个人的等待时间
s+=(n-i)*a[i]+a[i]; //最后加上自己的答疑时间a[i] (n-i)*a[i]+a[i]
}
cout<<fixed<<setprecision(2)<<s*1.0/n;
return 0;
}
3、士兵突击-2910
题解:
这个问题可以通过贪心算法来解决,即每次选择体重最轻的士兵上船,直到船的载重量无法再装载更多的士兵为止。这样可以确保装载的士兵数量最多。
步骤如下:
- 读入士兵的数量
n
和船的载重量c
。 - 读入每个士兵的体重,并将体重存入数组
w
。 - 对数组
w
进行排序,使士兵按体重从轻到重排列。 - 初始化变量
tmp
为0,用于记录当前船上士兵的总体重;初始化ans
为0,用于记录上船的士兵数量。 - 从最轻的士兵开始,依次尝试将每名士兵上船,即累加他们的体重到
tmp
。 - 如果
tmp
加上当前士兵的体重仍然小于等于船的载重量c
,则将这名士兵算作已上船,ans
加1。 - 如果加上当前士兵体重后
tmp
超过了c
,则停止尝试,因为不能再装载更多的士兵。 - 最后输出
ans
,即为最多可以装载的士兵数量。
#include <bits/stdc++.h>
using namespace std;
int main(){
//定义变量和数组
int n,c,w[2002]={
};
//输入士兵个数n和船载重量
cin>>n>>c;
//输入n个士兵兔体重
for(int i=0;i<n;i++