独木桥问题(算法)

dncs00000 2010-06-30 11:27:53
游戏规则:
有一家人,晚上要过一个独木桥。
但是他们只有一盏灯,而这盏灯只能使用30秒了。
要在灯熄灭前过这座桥,他们一家五口人每个人过桥的速度不同。
瘦人1秒,小胖3秒,姑娘6秒,大胖8秒,瘸子12秒。
每次只能过两个人,过去后,对岸要有一个人再把灯送回来。

写程序解决此问题
最好能用面向对象的思想写
...全文
1501 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
harizu76 2010-07-04
  • 打赏
  • 举报
回复
感觉就是考操作系统 进程轮转问题
fanster28_ 2010-07-04
  • 打赏
  • 举报
回复
飞雪的思路没问题,代码也没问题
#include <iostream>
#include <algorithm>
using namespace std;

int data[10005];
inline long long solve(int n)
{
long long result = 0;
for (;;)
{
if (n > 3)
{
int t1 = data[1] + data[0] + data[n-1] + data[1];
int t2 = (data[0]<<1) + data[n-1] + data[n-2];
if (t1 < t2) result += t1, n-=2;
else result += t2, n-=2;
} else if (n == 2) return result + data[1];
else return result + data[0] + data[1] + data[2];
}
}

int main()
{
int n;
while (scanf("%d", &n) == 1)
{
for (int i = 0; i < n; ++i) scanf("%d", data+i);
if (n==1){printf("%d\n", data[0]);continue;}
if (n==0){puts("0");continue;}
sort(data, data+n);
printf("%lld\n",solve(n));
}
return 0;
}

[Quote=引用 22 楼 aaa20090987 的回复:]

瘦人1秒,小胖3秒,姑娘6秒,大胖8秒,瘸子12秒。

还是可以的,不过不能像飞雪那样来贪心解
1:瘦人,小胖过去,用3秒
2:瘦人回来,用1秒
3:大胖,瘸子过去,用12秒
4:小胖回来,用3秒
5:瘦人,姑娘过去,用6秒
6:瘦人回来,用1秒
7:瘦人,小胖过去,用3秒

总共用了29秒,就全部过桥了
[/Quote]
webcq1999 2010-07-04
  • 打赏
  • 举报
回复
VC工程打包已经上传到CSDN,http://d.download.csdn.net/down/2509580/webcqsec 。
webcq1999 2010-07-02
  • 打赏
  • 举报
回复
正好有点空,输出结果如下:

8 个解
共 29 秒:|瘦人和小胖过桥(3秒)|瘦人回来(1秒)|姑娘和瘦人过桥(6秒)|小胖回来(3秒)|大胖和瘸子过桥(12秒)|瘦人回来(1秒)|小胖和瘦人过桥(3秒)|
共 29 秒:|瘦人和小胖过桥(3秒)|瘦人回来(1秒)|姑娘和瘦人过桥(6秒)|瘦人回来(1秒)|大胖和瘸子过桥(12秒)|小胖回来(3秒)|瘦人和小胖过桥(3秒)|
共 29 秒:|瘦人和小胖过桥(3秒)|瘦人回来(1秒)|大胖和瘸子过桥(12秒)|小胖回来(3秒)|姑娘和瘦人过桥(6秒)|瘦人回来(1秒)|小胖和瘦人过桥(3秒)|
共 29 秒:|瘦人和小胖过桥(3秒)|瘦人回来(1秒)|大胖和瘸子过桥(12秒)|小胖回来(3秒)|瘦人和小胖过桥(3秒)|瘦人回来(1秒)|姑娘和瘦人过桥(6秒)|
共 29 秒:|瘦人和小胖过桥(3秒)|小胖回来(3秒)|大胖和瘸子过桥(12秒)|瘦人回来(1秒)|姑娘和瘦人过桥(6秒)|瘦人回来(1秒)|小胖和瘦人过桥(3秒)|
共 29 秒:|瘦人和小胖过桥(3秒)|小胖回来(3秒)|大胖和瘸子过桥(12秒)|瘦人回来(1秒)|小胖和瘦人过桥(3秒)|瘦人回来(1秒)|姑娘和瘦人过桥(6秒)|
共 29 秒:|瘦人和姑娘过桥(6秒)|瘦人回来(1秒)|小胖和瘦人过桥(3秒)|小胖回来(3秒)|大胖和瘸子过桥(12秒)|瘦人回来(1秒)|小胖和瘦人过桥(3秒)|
共 29 秒:|瘦人和姑娘过桥(6秒)|瘦人回来(1秒)|小胖和瘦人过桥(3秒)|瘦人回来(1秒)|大胖和瘸子过桥(12秒)|小胖回来(3秒)|瘦人和小胖过桥(3秒)|
webcq1999 2010-07-02
  • 打赏
  • 举报
回复

class _person
{
public:
_person(LPCTSTR pName, int t){name=pName;consume=t;};
~_person(){};

CString name;
int consume;
};
typedef _person * pPerson;
typedef list<pPerson> lstPPerson;

typedef struct _path
{
int consume;
void * _pNode;
}path, * pPath;
typedef list<path> lstPath;

class _node;
typedef _node * pNode;
typedef list<pNode> lstPNode;
class _node
{
public:
_node(){at_source=TRUE;reach_consume=0;leaf=FALSE;parent=NULL;memset(desc,0,sizeof(desc));};
~_node()
{
lstPath::iterator it=path.begin();
while(it!=path.end())
{
delete (_node *)((*it)._pNode);
it++;
}
};

void Init(lstPPerson persons)
{
source=persons;
};
void Expand(lstPNode & lst)
{
lst.clear();
leaf=TRUE;
if(source.empty())
{
return;
}

if(at_source)
{
lstPPerson::iterator it1=source.begin();
while(it1!=source.end())
{
lstPPerson::iterator it2=it1;
it2++;
while(it2!=source.end())
{
_path t_path;
t_path.consume=(*it1)->consume>(*it2)->consume?(*it1)->consume:(*it2)->consume;

_node * pNode=new _node();
_snprintf(pNode->desc,sizeof(pNode->desc)-1,"%s和%s过桥(%d秒)",(*it1)->name,(*it2)->name,t_path.consume);
pNode->parent=this;
pNode->at_source=FALSE;
pNode->reach_consume=reach_consume+t_path.consume;

pNode->target=target;
pNode->target.push_back(*it1);
pNode->target.push_back(*it2);
lstPPerson::iterator tit=source.begin();
while(tit!=source.end())
{
if(tit!=it1 && tit!=it2)
{
pNode->source.push_back(*tit);
}
tit++;
}

t_path._pNode=pNode;
path.push_back(t_path);

lst.push_back(pNode);
leaf=FALSE;

it2++;
}
it1++;
}
}
else
{
lstPPerson::iterator it1=target.begin();
while(it1!=target.end())
{
_path t_path;
t_path.consume=(*it1)->consume;

_node * pNode=new _node();
_snprintf(pNode->desc,sizeof(pNode->desc)-1,"%s回来(%d秒)",(*it1)->name,t_path.consume);
pNode->parent=this;
pNode->at_source=TRUE;
pNode->reach_consume=reach_consume+t_path.consume;

pNode->source=source;
pNode->source.push_back(*it1);
lstPPerson::iterator tit=target.begin();
while(tit!=target.end())
{
if(tit!=it1)
{
pNode->target.push_back(*tit);
}
tit++;
}

t_path._pNode=pNode;
path.push_back(t_path);
lst.push_back(pNode);
leaf=FALSE;

it1++;
}
}
};

lstPPerson source;
lstPPerson target;

lstPath path;

int reach_consume;
BOOL at_source;

BOOL leaf;
pNode parent;
char desc[100];
};

typedef list<CString> lstStrings;



void CT_bridgeView::DoWork()
{
_person * pPerson;
pPerson=new _person("瘦人",1); m_Persons.push_back(pPerson);
pPerson=new _person("小胖",3); m_Persons.push_back(pPerson);
pPerson=new _person("姑娘",6); m_Persons.push_back(pPerson);
pPerson=new _person("大胖",8); m_Persons.push_back(pPerson);
pPerson=new _person("瘸子",12); m_Persons.push_back(pPerson);

_node * pNode=new _node();
pNode->Init(m_Persons);

m_WorkNode.push_back(pNode);

lstPNode lst;
lstPNode::iterator it=m_WorkNode.begin();
lstPNode::iterator t_it;
while(it!=m_WorkNode.end())
{
(*it)->Expand(lst);
t_it=lst.begin();
while(t_it!=lst.end())
{
m_WorkNode.push_back(*t_it);
t_it++;
}

it++;
}

CString str,t_str;
it=m_WorkNode.begin();
while(it!=m_WorkNode.end())
{
if((*it)->leaf && (*it)->reach_consume<=30)
{
str="";
pNode=*it;
lstPNode nodes;

while(NULL!=pNode)
{
nodes.push_back(pNode);
pNode=pNode->parent;
}

t_it=nodes.begin();
while(t_it!=nodes.end())
{
t_str=(*t_it)->desc;
str=t_str+"|"+str;

t_it++;
}
t_str.Format("共 %d 秒:",(*it)->reach_consume);
str=t_str+str;

m_Result.push_back(str);
}

it++;
}

CEdit & edit=this->GetEditCtrl();
str.Format("%d 个解\r\n",m_Result.size());
edit.ReplaceSel(str);
lstStrings::iterator it_str=m_Result.begin();
while(it_str!=m_Result.end())
{
edit.ReplaceSel((*it_str)+"\r\n");
it_str++;
}
}
AAA20090987 2010-07-02
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 dncs00000 的回复:]
期待着写出来的。。
[/Quote]

+1
deviosyan 2010-07-02
  • 打赏
  • 举报
回复
我也关注中 飞雪写的是有点问题把.
dncs00000 2010-07-02
  • 打赏
  • 举报
回复
期待着写出来的。。
dncs00000 2010-07-02
  • 打赏
  • 举报
回复
共有这些方案的:
第1种方案:瘦人和小胖(3)过桥 瘦人(1)回桥 瘦人和姑娘(6)过桥 瘦人(1)回桥 大胖和瘸子(12)过桥 小胖(3)回桥 瘦人和小胖(3)过桥 时间: 29 秒
第2种方案:瘦人和小胖(3)过桥 瘦人(1)回桥 瘦人和姑娘(6)过桥 小胖(3)回桥 大胖和瘸子(12)过桥 瘦人(1)回桥 瘦人和小胖(3)过桥 时间: 29 秒
第3种方案:瘦人和小胖(3)过桥 瘦人(1)回桥 大胖和瘸子(12)过桥 小胖(3)回桥 瘦人和小胖(3)过桥 瘦人(1)回桥 瘦人和姑娘(6)过桥 时间: 29 秒
第4种方案:瘦人和小胖(3)过桥 瘦人(1)回桥 大胖和瘸子(12)过桥 小胖(3)回桥 瘦人和姑娘(6)过桥 瘦人(1)回桥 瘦人和小胖(3)过桥 时间: 29 秒
第5种方案:瘦人和小胖(3)过桥 小胖(3)回桥 大胖和瘸子(12)过桥 瘦人(1)回桥 瘦人和小胖(3)过桥 瘦人(1)回桥 瘦人和姑娘(6)过桥 时间: 29 秒
第6种方案:瘦人和小胖(3)过桥 小胖(3)回桥 大胖和瘸子(12)过桥 瘦人(1)回桥 瘦人和姑娘(6)过桥 瘦人(1)回桥 瘦人和小胖(3)过桥 时间: 29 秒
第7种方案:瘦人和姑娘(6)过桥 瘦人(1)回桥 瘦人和小胖(3)过桥 瘦人(1)回桥 大胖和瘸子(12)过桥 小胖(3)回桥 瘦人和小胖(3)过桥 时间: 29 秒
第8种方案:瘦人和姑娘(6)过桥 瘦人(1)回桥 瘦人和小胖(3)过桥 小胖(3)回桥 大胖和瘸子(12)过桥 瘦人(1)回桥 瘦人和小胖(3)过桥 时间: 29 秒
baihacker 2010-07-01
  • 打赏
  • 举报
回复
这是引用的别人的分析。


题目分析:贪心,大胆假设,小心求证。
设最快的两人为f1,f2,设最慢的两人为l1,l2
1)直观来做,让最快的人带最慢的人过桥,让最快的人带灯回来,一直到结束。
2)利用“两人一组”这个条件,可假设最慢的两人,一起过桥,时间缩减很多。
3)为实验1)的方案,要解决灯问题,假设最快的两个人speed无限小,最慢两人speed无限大,可让最快两人负责把灯运回来。
4)明显,方法3)对比方法1),是省了l2的时间,增加了f2的时间,可通过简单推断得出:
if(f2*2<l2+f1)选方法3)
else 选方法1)


5)简而言之,将人按speed排序,每次判断f2,l2,f1的关系从而确定贪心的方案。



所犯错误:
之前没碰到过这类题型的贪心,只发掘出一种贪心方案。



总结:贪心,找极端情况,大胆假设,小心求证。
dncs00000 2010-07-01
  • 打赏
  • 举报
回复
能不能对solve(int n)里的写一下注释吗?看不大来。。。
dncs00000 2010-07-01
  • 打赏
  • 举报
回复
噢,这样子,那我好好看下、、
baihacker 2010-07-01
  • 打赏
  • 举报
回复
我只是写了一个求最短时间过桥问题的最优解的算法。
dncs00000 2010-07-01
  • 打赏
  • 举报
回复
也就是说跟这个有什么关系,看不出来,请指教
dncs00000 2010-07-01
  • 打赏
  • 举报
回复
看不懂其中的意思
dncs00000 2010-07-01
  • 打赏
  • 举报
回复
能具体写一下吗?
mousetec 2010-07-01
  • 打赏
  • 举报
回复
sixbusy 2010-07-01
  • 打赏
  • 举报
回复
图的遍历算法! 任何一个状态 都相当于 一个节点! 路长不同 ,找最短路径!
sixbusy 2010-07-01
  • 打赏
  • 举报
回复
最短路径问题!
地杰斯特拉算法!
djjlove_2008 2010-07-01
  • 打赏
  • 举报
回复
这类题貌似是智力题,并不是程序题吧。
加载更多回复(16)

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧