6.5.1题目描述
要举办一场机器人攀登接力赛,规定攀登总高度为m米。每个参赛机器人个数为n(n<=10),每个机器人只能攀登一次,且至少攀登1m,至多攀登k米,且只能在整米处接力。某队有n个机器人,在平时训练时进行了测试,得出每个机器人连续攀登1m,2m,3m…的时间,当机器人攀登路程越长其速度越慢。设计贪心算法求得最短攀登时间。
6.5.2思路描述
根据题意得到机器人攀登越长速度越低,而其速度就反映在每爬1m需要的时间,而原输入的时间是机器人连续攀登所消耗的总时间,所以第一步我们就需要将机器人连续攀登每1秒所用的时间算出来,进而进行直观的比较。
根据贪心法原则,将整个攀登视为m次1m的攀登,那么每次选择一个机器人去攀登时,就应该在所有机器人中选择当前其攀登1m用时最少的机器人。同时当选中该机器人后,其相应就已经攀登过1m,那么其最新的攀登1m所需的时间就需要根据上一步求出的时间进行更新。然后再在k个机器人中再找攀登1m用时最少的机器人,重复上述过程m次即可找到最短时间。
其中ans数组记录第一步处理后的攀登时间,selc数组记录k个机器人当前再攀爬1m各自所需的时间并保持更新,gone数组记录k个机器人当前已连续攀登的距离。
#include<iostream>
using namespace std;
int ans[15][25];
int bestk; //记录一次比较中最小时间对应的机器人
int k; //机器人总个数
void recul(int a[15][25],int n) //对机器人攀爬时间进行重计算,得到每隔1m的攀登时间
{
for(int j=1;j<=k;j++)
{
ans[j][1]=a[j][1];
for(int i=2;i<=n;i++)
ans[j][i]=a[j][i]-a[j][i-1];
}
}
int min(int a[]) //从k个机器人选择最优机器人完成下一米
{
int min=9999;
for(int i=1;i<=k;i++)
{
if(a[i]<min){
min=a[i];
bestk=i; //记录最优机器人
}
}
return min; //返回最小的时间
}
int func(int a[15][25],int m)
{
int time=0,count=0; //记录当前已走过的历程
int *selc=new int[k+1]; //选择数组
int *gone=new int[k+1]; //记录每个机器人已走的距离
for(int i=1;i<=k;i++){
selc[i]=a[i][1]; //对初始选择数组赋初值
gone[i]=1; //已走距离初始化
}
while(count!=m){
count++;
time=time+min(selc);
gone[bestk]++;
selc[bestk]=a[bestk][gone[bestk]];
}
cout<<"每个机器人应攀登高度分别为:";
for(int i=1;i<=k;i++)
cout<<gone[i]-1<<" ";
cout<<endl<<"花费的最少时间为:"<<time;
}
int main()
{
int m,n;
int a[15][25];
cout<<"输入参赛机器人数,机器人攀登最大高度,总攀登高度:";
cin>>k>>n>>m;
for(int i=1;i<=k;i++)
{
cout<<"输入第"<<i<<"个机器人的攀登时间:";
for(int j=1;j<=n;j++)
cin>>a[i][j];
}
recul(a,n);
func(ans,m);
}