实验二 贪心算法的应用
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验二贪心算法的应用
一、实验目的
1.掌握贪心算法的基本概念和两个基本要素
2.熟练掌握贪心算法解决问题的基本步骤。
3.学会利用贪心算法解决实际问题。
二、实验内容
1.问题描述:
题目二:会场安排问题
假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的贪心算法来进行安排。试编程实现对于给定的k个待安排活动,计算使用的最少会场。输入数据中,第一行是k的值,接下来的k行中,每行有2个正整数,分别表示k个待安排活动的开始时间和结束时间,时间以0点开始的分钟计。输出为最少的会场数。
输入数据示例
5
1 23
12 28
25 35
27 80
36 50
输出数据
3
三、算法分析
Stept1:输入各个活动的开始时间(s)和结束时间(e),初始化各活动的会场号。Step2:按活动的开始时间和活动时间排序,s最早(第一优先级)和持续时间最短(第二优先级)的活动排在最前。
Step3:执行贪婪算法,即s最早和持续时间最短的优先安排会场,并记录会场号,其余活动的s大于或等于已安排活动的e的安排在同一会场,若某活动的s
小于安排活动的e,则安排在另一会场,记录会场号,依次循环,直到所有活动均被安排。
Step4:统计会场号数,输出。
时间复杂度:O(n)
算法时间:O(nlogn)
核心算法:
void swap(Active &a,Active&b)
{
Active t;
t=a;
a=b;
b=t;
}
//活动时间排序
for(i=1;i<=k;i++)
{
for(j=i;j<=k;j++)
{
if(a[i].s>a[j].s)
swap(a[i],a[j]);
if(a[i].s==a[j].s)
{
if(a[i].e>a[j].e)
swap(a[i],a[j]);
}
}
}
四、程序调试及运行结果分析
五、源代码
#include
using namespace std;
#define M 50 //最大活动数
struct Active
{
int s;//开始时间
int e;//结束时间
int no;//预安排会场号
}a[M];
//两元素交换位置
void swap(Active &a,Active&b)
{
Active t;
t=a;
a=b;
b=t;
}
void main()
{
int k;
inti,j;
cout<<"输入待安排活动数:"< cin>>k; cout<<"输入待安排活动的开始时间和结束时间:"< //输入活动时间 for(i=1;i<=k;i++) { cin>>a[i].s>>a[i].e; a[i].no=0; } //活动时间排序 for(i=1;i<=k;i++) { for(j=i;j<=k;j++) { if(a[i].s>a[j].s) swap(a[i],a[j]); if(a[i].s==a[j].s) { if(a[i].e>a[j].e) swap(a[i],a[j]); } } } int sum=1;//使用的会场数初始化 int n; a[1].no=sum; for(i=2;i<=k;i++) { for(n=1;n { if(a[n].no!=0&&a[n].e<=a[i].s) { a[i].no=a[n].no; a[n].no=0;//已经安排过的活动就不再比较 break; } } if(n==i) { sum+=1; a[i].no=sum; } } cout<<"输出最少会场数:\n"< system("pause"); } 2.问题描述: 题目四:汽车加油问题 一辆汽车加满油后,可行使n千米。旅途中有若干个加油站。若要使沿途加油次数最少,设计一个有效算法,对于给定的n和k个加油站位置,指出应在哪些加油站停靠加油才能使加油次数最少。输入数据中,第一行有2个正整数,分别表示汽车加满油后可行驶n千米,且旅途中有k个加油站。接下来的1行中,有k+1个整数,表示第k个加油站与第k-1个加油站之间的距离。第0个加油站表示出发地,汽车已加满油。第k+1个加油站表示目的地。输出为最少的加油次数,如果无法到达目的地,则输出“No Solution”。 实验提示: 把两加油站的距离放在数组中,a[1..k]表示从起始位置开始跑,经过k个加油站,a[i]表示第i-1个加油站到第i个加油站的距离。汽车在运行的过程中如果能跑到下一个站则不加油,否则要加油。