从前,有5个海盗,100个金币,这5个海盗都是及其聪明并且贪婪,要把这100个金子给分了。5个人轮流提方案,如果超过半数以上的人同意则此方案通过,否则将提方案的这个人给杀了(比如扔进大海)。问最后的分配方案。
作为推广,我们可以假设有n个海盗,n个金币,解决程序(Mathematica)如下:
z = 10;
gold = 200;
(*程序的输入 : 总的海盗数(需 ≥ 5); 总的金币数*)
p = Table[0, {i, z}];
(*海盗拥有金钱列表*)
p[[1]] = 0;
p[[2]] = 0;
p[[3]] = 0;
p[[4]] = gold;
(*4个海盗时的情况, 作为初始值*)
f = 5;
(*从海盗数5开始计算*)
While[
f ≤ z,
a = Table[0, {i, f - 1}];
x = Table[a[[1]]++;
Do[If[a[[j]] == 2, a[[j]] = 0; a[[j + 1]]++], {j, f - 1}]; a, {k, 2^(f - 1) - 1}];
(*所有可能的投票情况*)
n = IntegerPart[(f - 1)/2] + 1;
(*至少要得到n个人的支持*)
y = Table[If[Count[x[[i]], 1] == n, x[[i]], 0], {i, Length[x]}];
y = Union[y]; y = Rest[y];
(*y存储这种方案通过时的支持者情况*)
v = Table[0, {i, Length[y]}, {j, f - 1}];
Do[If[y[[i, j]] == 1, v[[i, j]] = p[[j]] + 1], {i, Length[y]}, {j, f - 1}];
(*v存储各种情况要发放的金币数目, 对支持者需比此方案否决的情况多发一个金币, 反对者不发
*)
s = Table[Apply[Plus, v[[i]]], {i, Length[y]}];
(*选出发放金币最少的那种方案*)
p[[f]] = gold - Min[s];
q = Do[If[Sum[v[[i, j]], {j, f - 1}] == Min[s], Return[v[[i]]]], {
i, Length[y]}];
Do[p[[i]] = q[[i]], {i, f - 1}];
f++; Print[f - 1]
]
p
程序说明:
1. 应该有很多种分配方案,但此程序之给出一种,如果要给出所有,要对程序作一点修改。
2. 适用于海盗数目大于或等于5个的情况。少于5个很容易可以人工推出。如果一定要加入少于5个的情况也可以,只是程序稍微长一点。
3. 本程序不适宜解海盗数目太多的情况,超过20就运行的很慢了。运行时间大约呈2^(海盗人数)增长。
4. 有问题请联系 13321331929 黄俊挺
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment