海盗分金是一个问题, 具体问题可以查询百度百科, 这里我主要是在算法上做一些研究。
首先, 把这个问题转换为一个递归的算法问题, 描述为, 如果我知道了上一家的分法, 我如何能够使我的利益最大化呢?
现假定有5个人分, 金币总数是100, 那么第二个人的分法是1, 1, 0, 98, 那么第一个人需要的就是拉拢分的最少的两人, 然后给他们多一个金币, 这样就可以取得他们的支持了, 所以第一个人的分法是2, 0, 1, 0, 97 或者0, 2, 1, 0, 97.
所以转换为程序之后, 我们可以分任意金币和任意的人了。
#include <iostream>
using namespace std;
#include <vector>
#include <assert.h>
const int max_gold = 100;
int gold3[] = {0, 0, max_gold};
void bubbleSort(vector<int> &unsorted, vector<int> &index)
{
int Length = unsorted.size();
for (int i = 0; i < Length; i++)
{
for (int j = i; j < Length; j++)
{
if (unsorted[i] > unsorted[j])
{
int temp = unsorted[i];
unsorted[i] = unsorted[j];
unsorted[j] = temp;
temp = index[i];
index[i] = index[j];
index[j] = temp;
}
}
}
}
vector<int> getGoldN(int n)
{
// at least 3 people
assert(n >= 3);
vector<int> re;
re.resize(n);
if (n == 3)
{
// 3 people
for (int i = 0; i< 3; i++)
{
re[i] = gold3[i];
}
return re;
}
else
{
// n > 3
// old result
vector<int> old_re = getGoldN(n-1);
vector<int> old_index;
old_index.resize(n-1);
for (int i = 0; i< n-1; i++)
{
old_index[i] = i;
}
// sort old
bubbleSort(old_re, old_index);
// how many people you need
int support_people = n/2;
// assign value
for (int i = 0; i< support_people; i++)
{
int now_index = old_index[i];
int now_gold = old_re[i];
re[now_index] = now_gold+1;
}
for (int i = support_people; i< n-1; i++)
{
int now_index = old_index[i];
re[now_index] = 0;
}
int last_gold = max_gold;
for (int i = 0; i< n-1; i++)
last_gold -= re[i];
re[n-1] = last_gold;
return re;
}
}
void outPut(vector<int> re)
{
for (int i = 0; i< re.size(); i++)
{
cout<<re[i]<<"\t";
}
cout<<endl;
}
int main()
{
vector<int > re = getGoldN(207);
outPut(re);
system("pause");
return 0;
}
比如, 我分100个人, 结果是
但这个问题并未完结。 还有着如下的思考:
首先, 我这个模型, 条件是大于百分之五十才行, 而不是大于等于百分之五十, 因为很明显, 如果等于百分之五十即可的话, 那么只剩下两个人, 那么第一个人会分100, 0. 所以地推一下, 剩三个人, 第一个人会分99, 0, 1……
其次是考虑一下, 比如第三个人, 他知道如果只有三个人分, 那时候他的利益才最大化, 那么他是不是会总是投反对票呢?
然后是考虑一种极端情况, 海盗人超级多, 大于200个呢? 这个时候, 按照我的算法, 甚至会是负数……
这些问题等以后在思考吧。