【作业】最小路径

题目

一个m * n的列表中,每格上有一个数,找到从左上角到右下角的路径,经过所有格的数之和最少。
注意,每次位移只能向右或向下。

结果

下面path里的编号,是指从上到下,从左到右的格子编号。

131
151
421

the path is: 0 1 2 5 8
the values is: 1 3 1 1 1
total: 7

123
456

the path is: 0 1 2 5
the values is: 1 2 3 6
total: 12

114
352
111

the path is: 0 3 6 7 8
the values is: 1 3 1 1 1
total: 7

代码

这里算法很简单,就是普通的深度优先递归。
为生成路径信息时,我之前一直认为每递归一条路径时,要返回其完整路径。但实际上这很愚蠢,因为这会生成非常多的路径信息, 数目大概是 ∑ k = 1 n + m − 2 2 k \displaystyle \sum_{k=1}^{n+m-2} 2^k k=1n+m22k。其实只要让每个格子,标记下一个最小路径的位置即可,大小也就m*n的大小。

#include <iostream>

class EGrid {
public:

	EGrid(int* data, int row, int col) :col_count(col), row_count(row){
		const int t = row * col;
		grid_data = new int[t];
		next_min_index = new int[t];
		step_count = row + col - 1;
		result = new int[step_count];
		memcpy(grid_data, data, sizeof(int) * t);
		total = 0;
	}

	~EGrid() {
		delete[] grid_data;
		grid_data = nullptr;
		delete[] result;
		result = nullptr;
		delete[] next_min_index;
		next_min_index = nullptr;
	}

	int _find_min_path(int cur_row, int cur_col) {
		if (cur_row >= row_count || cur_col >= col_count)
			return -1;
		
		const int cur_index = cur_row * col_count + cur_col;
		int cur_value = grid_data[cur_index];
		if (cur_row == row_count - 1 && cur_col == col_count - 1)
			return cur_value;

		const int r1[] = { cur_row + 1, cur_col };
		const int r2[] = { cur_row, cur_col+1 };

		int res1 = _find_min_path(r1[0], r1[1]);
		int res2 = _find_min_path(r2[0], r2[1]);
		bool is_res_1 = true;
		if (res1 == -1 && res2 == -1)
			return -1;
		if (res1 == -1 && res2 != -1)
			is_res_1 = false;
		else if (res1 != -1 && res2 == -1)
			is_res_1 = true;
		else
			is_res_1 = (res1 < res2);
		const int* rs = (is_res_1 ? r1 : r2);
		const int next_index = rs[0] * col_count + rs[1];
		next_min_index[cur_index] = next_index;
		const int res = is_res_1 ? res1 : res2;
		if (next_index == 4)
			int k = 22434;
		return res + cur_value;

	}

	const int* find_min_path() {
		result[0] = 0;
		total = 0;
		total = this->_find_min_path(0, 0);
		for (int i = 1; i < step_count; ++i) {
			result[i] = next_min_index[result[i - 1]];
		}
		return this->result;
	}

	void output_res() {
		//int total = 0;
		std::cout << std::endl;
		for (int j = 0; j < col_count; ++j) {
			std::cout << "|" << grid_data[j] ;
		}
		std::cout << "|" << std::endl;
		for (int j = 0; j < col_count; ++j) {
			std::cout << "|:--:";// << grid_data[j];
		}
		std::cout << "|"<< std::endl;
		for (int i = 1; i < row_count; ++i) {
			int row_i = i * col_count;
			for (int j = 0; j < col_count; ++j) {
				std::cout << "|" << grid_data[row_i + j];
			}
			std::cout << "|"<< std::endl;
		}

		std::cout << "the path is:";
		for (int i = 0; i < step_count; ++i) {
			std::cout << " " << result[i];
		}
		std::cout << std::endl << "the values is:";
		for (int i = 0; i < step_count; ++i) {
			const int index = result[i];
			const int v = this->grid_data[index];
			std::cout << " " << v;

		}
		std::cout << std::endl << "total: " << total;	
	}

	int col_count;
	int row_count;
	int step_count;

	int* grid_data;
	int* next_min_index;
	int* result;
	int* temp_path;
	int* temp_path2;
	int total;
};

void find_min_path() {
	{
		int data[] = {
			1, 3, 1,
			1, 5, 1,
			4, 2, 1
		};
		EGrid g(data, 3, 3);
		g.find_min_path();
		g.output_res();
	}
	{
		int data[] = {
		1, 2, 3,
		4, 5, 6
		};
		EGrid g(data, 2, 3);
		g.find_min_path();
		g.output_res();
	}
	{
		int data[] = {
			1, 1, 4,
			3, 5, 2,
			1, 1, 1
		};
		EGrid g(data, 3, 3);
		g.find_min_path();
		g.output_res();
	}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值