「题解」花生采摘

题目描述

鲁宾逊先生有一只宠物猴,名叫多多。这天,他们两个正沿着乡间小路散步,突然发现路的告示牌上贴着一张小小的纸条:“欢迎免费品尝我种的花生!——熊字”。
鲁宾逊先生和多多都很开心,因为花生正是他们的最爱。在告示牌背后,路边真的有一块花生田,花生植株整齐地排列成矩形网格(如图1)。有经验的多多一眼就能看出,每棵花生植株下的花生有多少。为了训练多多的算术,鲁宾逊先生说:“你先找出花生最多的植株,去采摘它的花生;然后再找出剩下的植株里花生最多的,去采摘它的花生;依此类推,不过你一定要在我限定的时间内回到路边。”

我们假定多多在每个单位时间内,可以做下列四件事情中的一件:
1.从路边跳到最靠近路边(即第一行)的某棵花生植株;
2.从一棵植株跳到前后左右与之相邻的另一棵植株;
3.采摘一棵植株下的花生;
4.从最靠近路边(即第一行)的某棵花生植株跳回路边。
现在给定一块花生田的大小和花生的分布,请问在限定时间内,多多最多可以采到多少个花生?注意可能只有部分植株下面长有花生,假设这些植株下的花生个数各不相同。
例如在图2所示的花生田里,只有位于(2,5),(3,7),(4,2),(5,4)的植株下长有花生,个数分别为13,7,15,9。沿着图示的路线,多多在21个单位时间内,最多可以采到37个花生。

输入格式

输入的第一行包括三个整数,M,N和K,用空格隔开,表示花生田的大小为M*N(1<=M,N<=20),多多采花生的限定时间为K(0<=K<=1000)个单位时间。
接下来的M行,每行包括N个非负整数,也用空格隔开,第i+1行的第j个整数Pij(0<=Pij<=500)表示花生田里植株(i,j)下花生的数目,0表示该植株下没有花生。

输出格式

输出包括一行,这一行只包含一个整数,即在限定时间内,多多最多可以采到花生的个数。

样例

  样例输入

   6  7  21
   0  0  0  0  0  0  0
   0  0  0  0 13 0  0
   0  0  0  0  0  0  7
   0 15 0  0  0  0  0
   0  0  0  9  0  0  0
   0  0  0  0  0  0  0

  样例输出

      37

题解

这道题其实挺简单的,最容易想到的方法自然是:

输入
寻找剩余植株中的最大值
判断能否采摘后及时返回
累加
输出

但难点在于寻找剩下的植株中花生最多的,其实对于一个二维矩阵,用搜索自是最好的办法
但是,如果只搜最大值的话,那么会造成多次搜索超时
于是,我们将二维矩阵的信息压入一维的结构体数组,并以花生数排序
然后再循环就轻松的多了
你可以先在输入时将二维信息收入一维,在排序
也可以边输入,边将数据变为一维排序

代码

#include<cstdio>
#include<algorithm>
using namespace std;

const int M = 25;
int m, n, k;
int ans;

struct place{
	int x;
	int y;
	int peanut;
}a[625];

void find(int temp, int step) {
	int num = step;
	num += abs(a[temp - 1].x - a[temp].x) + abs(a[temp - 1].y - a[temp].y) + 1;
	if(num + a[temp].x > k) return ;
	step = num;
	ans += a[temp].peanut;
	find(++ temp, step);
}

bool cmp(place x, place y) {
	return x.peanut > y.peanut;
}

int main() {
	scanf("%d %d %d", &m, &n, &k);
	for(int i = 1; i <= m; i ++) {
		for(int j = 1; j <= n; j ++) {
			scanf("%d", &a[(i - 1) * n + j].peanut);
			a[(i - 1) * n + j].x = i;//信息处理
			a[(i - 1) * n + j].y = j;
		}
	}
	sort (a + 1, a + 1 + n * m, cmp);
	a[0].x = 0;//初始化
	a[0].y = a[1].y;
	find(1, 0);
	printf("%d", ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/yu_______chen/article/details/107387673