四人过桥问题

问题:四人夜过桥,步行时间分别为 1、2、5、10 分钟,四人只有一台手电筒,一趟最多两人过桥,一趟过桥须持手电筒,时间以最慢者计,问 17 分钟内可否过桥,如何过桥?


#include <iostream>
using namespace std;

const int n = 4;   //4个人
const int size = 64;

int position[n];   //表示每个人的状态  1为已经过桥  0为未过桥

int index, tmpscheme[size];   //tmpscheme临时时间方案   

int mintime = 1000;//最少时间初始值

int time[n] = { 1, 2, 5, 10 };  //每个人过桥时间

int c;

//remainder表示未过桥的人   curtime表示当前已经花的时间   direction表示方向  1为过桥方向  0为反方向
void fn(int remainder, int curtime, int direction)
{
	if (remainder == 0)
	{
		if (curtime == 17)
		{
			int i = 0;
			for (; i+3 < c && tmpscheme[i] >= 0; i += 3)
				cout << time[tmpscheme[i]] << "-" << time[tmpscheme[i + 1]] << "  " << time[tmpscheme[i + 2]] << "   ";
			cout << time[tmpscheme[i]] << "-" << time[tmpscheme[i + 1]];
			cout << endl;
		}
		mintime = curtime;

	}
	else if (direction)
	{
		for (int i = 0; i < n; ++i)
		{
			if (!position[i] && curtime + time[i] <= mintime)
			{
				c++;
				tmpscheme[index++] = i;
				position[i] = 1;
				for (int j = 0; j<n; ++j)
				{
					int TmpMax = (time[i]>time[j] ? time[i] : time[j]);
					if (position[j] == 0 && curtime + TmpMax<=mintime)
					{
						c++;
						tmpscheme[index++] = j;
						position[j] = 1;
						fn(remainder - 2, curtime + TmpMax, !direction);
						position[j] = 0;
						c--;
						tmpscheme[--index] = -1;
					}
					
				}
				position[i] = 0;
				c--;
				tmpscheme[--index] = -1;
			}
		}
	}
	else
	{
		for (int j = 0; j<n; j++)
		{
			if (position[j] == 1 && curtime + time[j] <= mintime)
			{
				c++;
				tmpscheme[index++] = j;
				position[j] = 0;
				fn(remainder + 1, curtime + time[j], !direction);
				position[j] = 1;
				c--;
				tmpscheme[--index] = -1;
			}
		}
	}
}


int main()
{
	for (int i = 0; i<size; i++)        // 初始方案内容为负值,避免和人员标号冲突
		tmpscheme[i] = -1;
	fn(n, 0, 1);                   // 查找最佳方案
	cout << "MinTime=:" << mintime << endl;

	return getchar();
}


主要思路 就是暴力递归


附上大神作品一篇   实在看不懂   留着以后看。

http://blog.csdn.net/hikaliv/article/details/4479956

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值