找回密码
 欢迎注册
查看: 73967|回复: 20

[原创] 百囚问题之【你是最后一个出来的吗?】

[复制链接]
发表于 2013-5-1 16:35:51 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
国王招来100个囚犯,对他们说:你们犯了死罪,理应判处死刑。但我今天决定开恩,给你们一次逃生的机会。你们稍后将会被分开地关在100个房间里——1个房间只关1个人。这些房间都是密闭的,在里面无法获得任何外界的信息,直到房间门被打开——我会按照某种顺序【注1】,一个一个地打开你们的房间。
精华
每打开一个房间,该囚犯都会被带到一个特殊的房间——这个房间里有6盏灯。最初的时候,6盏灯都是灭的。看了这6盏灯之后,该囚犯必须回答该问题:“你是最后一个出来的吗?”如果答错了,那么逃生失败,全体杀头。如果答对了,那么该囚犯可以改变若干盏灯的状态——点亮或者熄灭,然后回到自己的房间。除了灯的状态之外,该囚犯在该房间里留下的任何痕迹都会被清除。如果100个人均回答正确,那么逃生成功,全体无罪释放。现在你们可以商量如何尽可能地全体答对问题。若干小时过后,你们将会被完全分开,接受生死考验。 注1:一共有 100*99*98*...*1 = 100! 种顺序,国王按照任何1种顺序打开房间的概率都是相等的,均为 1/100! 。 这100个囚犯希望活命的概率尽可能大。 问:最佳策略是什么?最大的活命概率是多少?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-5-1 18:13:13 | 显示全部楼层
如果6盏灯是理想的冷光源灯,不能利用灯的热度来揣度顺序,就纯粹靠编码方法了。 记灭为0,明为1, 6灯之明灭可表64个6位二进制编码。第1人进去后看到的是000000,他改成000001,第2个人看到000001后改成000010,依此类推,第64个人看到的是111111,他改回000000,然后第65至99号重复1~35号的作法,结果第36人和第100人面临相同的状态100011,他们答对的概率都是50%,所以按照这种方法,活命的概率是25%。 还有改进余地吗?似乎有,因为假使增加至128个囚犯,使得每个编码恰管2人,活命的概率也能达到25%。 现在人数减少了28人,可以只用50个编码就能达到25%的活命概率,如何充分利用14个冗余码来提高活命概率呢?

评分

参与人数 1金币 +3 收起 理由
KeyTo9_Fans + 3 反应很快呀,我也只找到活命率$25%$的方案~ ...

查看全部评分

毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-5-1 18:35:03 | 显示全部楼层
如果恰好64个囚犯,那么按照上述编码方法可以100%成功。现在先考虑极端情况:把100人改成65人,最佳策略能创造多大的活命概率?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2013-5-1 23:37:35 | 显示全部楼层
百度数学吧虽然水资源丰富,但水里却隐藏着不少大神牛级别的人物。 已有大牛在这个贴子里给出了逃生率为$64%$的方案: http://tieba.baidu.com/p/2300149695 虽然如此,我们还是有机会比数吧的神牛们做得更好: 要么给出逃生率更高的方案,要么证明所有的方案逃生率都不大于$64%$。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-5-4 16:41:15 | 显示全部楼层
猜测64%为最高逃生率。 尝试寻找0-64之间的某些自然数做连乘积,使得连乘积为一个确定常数, 并且任意破坏其中的若干自然数为1,都会使得结果常数发生变化。 可能是我没做好,没有找到这个组合。 随机数连乘积唯一化1.GIF 尝试取若干0-64之间的素数组合做连乘,取模映射为小于64的自然数,其中把0当1用 用素数做模时,得到的余数分布较均匀,其他0-64非素数中的模,得到的余数分布不平衡 我测试的结果不太理想。 随机数连乘积唯一化.GIF —————————————————————————————————— 还是用加法求和得到的逃生率高,根据数吧的神牛的方法,测试得到 逃生率在64%左右。 C++测试代码:
  1. #include <cstdlib>
  2. #include <iostream>
  3. #include <time.h>
  4. #include <stdio.h>
  5. using namespace std;
  6. int main(int argc, char *argv[])
  7. {
  8. int testcount=1000000;
  9. int *p=new int[100];
  10. int unpass_forecast=36;
  11. int module_forecast=64;
  12. int result,test_result;
  13. int pass=0,unpass=0;
  14. int n,i,j;
  15. int random,temp;
  16. for (n=0;n<testcount;n++)
  17. {
  18. srand(n);
  19. j=0;
  20. result=0;
  21. test_result=0;
  22. for (i=0;i<100-unpass_forecast;i++){
  23. p[j++]=1;
  24. result+=1;
  25. result%=module_forecast;
  26. }
  27. for (i=0;i<unpass_forecast;i++){
  28. p[j++]=0;
  29. }
  30. for (i=0;i<100;i++){
  31. random=rand()%100;
  32. temp=p[i];
  33. p[i]=p[random];
  34. p[random]=temp;
  35. }
  36. for (i=0;i<100;i++){
  37. if (p[i]==0) continue;
  38. test_result+=p[i];
  39. test_result%=module_forecast;
  40. if (test_result == result)
  41. break;
  42. }
  43. if (i==99)
  44. pass++;
  45. else
  46. unpass++;
  47. }
  48. cout<<(int)(result)<<endl;
  49. cout<<pass/(double)(pass+unpass)<<endl;
  50. delete [] p;
  51. system("PAUSE");
  52. return EXIT_SUCCESS;
  53. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-5-4 17:07:57 | 显示全部楼层
考虑模某个素数的序列如何?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-5-4 17:31:33 | 显示全部楼层
或者找个函数, 上个的输出当作这个的输入 n=1..100时候 当且仅当n=100时候,等于某个唯一不重复值
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-5-4 22:34:42 | 显示全部楼层
是啊,可以为每个人分配一个函数f(nth,protocol,last_input) 用nth标记每个人的ID,这个函数只和(nth,约定的协议,该人看到的灯的状态)有关 用每次将灯的状态+1的方法,最多可以标识出64个人 其他36人总是回答不是,那么逃生率为64% 协议约定每个人可以采取的策略是: 1.总是回答是 2.总是回答不是 3.是和不是都可以依据f的参数回答 显然若有一个人总是回答是(和看到的灯状态无关),那么逃生率将不大于1% 因此最后一个人参考灯的状态来回答,其逃生率的一个下界将是64%。 选择的函数f(.),需要满足: 1.函数f(.)乱序复合100次,得到的值c都相同 2.从函数f(.)乱序复合n次(0<=n<=99)后,得到的值不等于c 否则,逃生率将不大于50%。 因为不满足上述两个条件时,会有两个人遇到相同的灯状态c,这两个人的nth先后顺序无法区分 因为总是可以交换这两个人的nth。 还是没有证明逃生率不大于64%,是否存在满足上述条件的函数使得逃生率等于100%或大于64%呢?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-5-5 08:08:37 | 显示全部楼层
昨晚想了一晚,不可能大于64%,但是不会证明 因为状态最多只可以有64个
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2013-5-5 12:09:40 | 显示全部楼层
6盏灯可以给出64个不同信息。这似乎是留给这100个囚犯的唯一联系方式。 “除了灯的状态之外,该囚犯在该房间里留下的任何痕迹都会被清除。”但有一个“痕迹”是无法清除的:时间。囚犯依次被带到同一个房间,这样每个囚犯将占去一定的时间,100个囚犯共占用的时间必然有一个下限,当然也有一个上限(不会超过决定开恩的当天)。 囚犯可以利用64个信息,给下一个囚犯一个有序信息,当64个信号用完之后再从头来。可以假定这64个信息依次代表0~63,那么给最后一个囚犯的信息必然是“35”。问题是35将出现两次,若能够确定这两个“35”的不同之处,囚犯就可以作出正确决定。此时“时间”痕迹就能够发挥它的作用了。若一个囚犯占用5—10分钟,第一个“35”信息应该在之后2小时45分钟到5小时30分钟出现,而最后一个“35”信息将在之后8小时15分——16小时30分个小时出现。这个差别比较大,囚犯也可以事先商量一个控制时间的原则,尽量将这个差别保持在某个较大的范围之内。这样后一个看到“35”信息的囚犯回答“是”,其余都回答“不是”,活命概率就可以得到百分之百。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-11-22 15:57 , Processed in 0.030807 second(s), 20 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表