题目2:有n个人参加一个马拉松接力游戏,游戏规定每个人可以根据自己的情况随时终止游戏并由下一个人继续接力。由于每个人的情况不同,即使同一个人也不可能在整个游戏过程中永远保持很好的状态。因此要求他们在比赛前根据每个人的情况需要制定一个接力规则,使整个比赛的时间越少越好。请编写程序帮助他们制定这样的接力方案。
输入要求:输入的第1行有三个整数n,k和m,分别表示参加接力的人的个数,每个人最多可以跑的公里数以及接力赛的距离(以公里为单位)。其后的n行,每行有k个整数,分别表示每个人跑整数1公里,2公里,….,K公里所花费的时间(以秒为单位,整数)。游戏要求每个人都必须参加比赛,且每次只能跑到整数公里后才能换人。
输出要求:输出1个整数,表示这些人跑完整个接力赛最少要花多少时间。
样例输入:
5 10 25
24 49 75 102 130 160 192 230 270 320
23 48 75 103 139 181 224 274 344 415
22 49 80 180 280 380 480 580 680 780
25 51 80 120 170 220 270 320 370 420
23 49 79 118 158 200 250 300 350 400
样例输出:
727
大概思路如下
该问题求解接力赛所用的最短时间,因为每个人必须参加并且只能跑一次,所以每个人必须不间断跑n公里,最后总和为25公里。因为每个人的时间都是随着里程数的增多而增多的,所以可以将25公里分为25*1公里,每次分配只要找一公里时间最快的就可以。因此可以根据输入求得一个单位公里的时间数组,每次搜寻只要找该列最快的即可。因此可以设置一个Sub[i][j]的二维数组,存储每个人单位时间内花费的时间,如下所示:
24 25 26 27 28 30 32 38 40 50
23 25 27 28 36 42 43 50 70 71
22 27 31 100 100 100 100 100 100 100
25 26 29 40 50 50 50 50 50 50
23 26 30 39 40 42 50 50 50 50
因为对同一个人来说,第j列花费的时间一定是<=第j+1列的,但对于不同的人,花费的时间有差异,因此在搜索时,设置Min为最小值,根据Sub[i][j]的值及时更新Min的值。当总公里数=m时结束搜索。
二 程序代码
#include<iostream>
using namespace std;
#define Maxsize 999
int grade[Maxsize][Maxsize] ;//存放每个人的成绩
int Sub[Maxsize][Maxsize];//分块之后每个人1公里的时间
int Min;//比较数
int m, n, k;//总里程数,人数,最大公里数,
int sum = 0;//总时长
int km = 0;//里程数
//可以把25公里分割成25块,每次找一公里中跑的最快的那个
void Search()
{
for (int i = 1;i <= n;i++)
{
for (int j = 1;j <= k;j++)
{
Sub[i][j] = grade[i][j] - grade[i][j - 1];
}
}
}
void Calculate(int a)
{
int i = 1;
int j = 1;
int Min = Maxsize;
//每公里遇到需要派人时,首先挑选时间最短的
while (km <m)
{
if (i % (n+1) == 0)//按Sub数组的列进行搜索
{
i = 1;
j++;
}else
{
if (Sub[i][j] <= Min)//选中该人
{
Min = Sub[i][j];
sum += Sub[i][j];
i++;//进行下一次选择
km++;
}
if (Sub[i][j] > Min) //当前比最小的大
{
if (Sub[i][j] < Sub[i][j + 1] && Sub[i][j]<=a)
{
Min = Sub[i][j];//存储较大的元素,方便后续比较
sum += Sub[i][j];
km++;
i++;
}
else i++;
}
}
}
}
int main()
{
memset(grade, 0, sizeof(grade));
memset(Sub, 0, sizeof(Sub));
cin >> n >> k >> m;
for (int i = 1;i <= n;i++)
{
for (int j = 1;j <= k;j++)
{
cin >> grade[i][j];
}
}
Search();
int a = Sub[1][k - 1];//单位公里内允许花费的最大时间
Calculate(a);
cout << sum;
return 0;
}