你的方法有很多问题。
主要的一点是,由于这不是一个简单的两人最小最大,你不能简单地递归返回一个分数。对于给定玩家的每次游戏,您必须返回每个玩家将获得的分数。比如:
无效分数(int currentPlayer,int toWrite,int outScores[],int nbOut)
将返回 outScores 中所有玩家的得分,如果 currentPlayer 要写一个或两个数字,从 toWrite,用 nbOut 玩家已经出局了。
不过,这并不是最优的。递归地尝试 10 名玩家的所有解决方案意味着要降低 50 多个级别,分支因子为 2。您需要一些动态编程来提高效率。
我确实编写了代码。它适用于 4 名玩家,最大值为 10。对于更多的玩家来说,它变得非常慢。正如我所说,动态编程是您正在寻找的,在这里。
另外,我假设一个玩家宁愿只玩一次,如果它仍然会以相同的顺序输掉。
#include <memory.h>
#include <vector>
#include <iostream>
using namespace std;
const int NB_PLAYERS = 3;
const int MAX_VALUE = 10;
vector<pair<int, int>> scores(int currentPlayer, int toWrite, int outScores[], int nbOut)
{
if (outScores[currentPlayer] == -1) // we're already out, lets just have the next player play
{
return scores((currentPlayer + 1) % NB_PLAYERS, toWrite, outScores, nbOut);
}
if (toWrite == MAX_VALUE) // one player is out
{
vector<pair<int, int>> ret;
if (nbOut + 2 != NB_PLAYERS)
{
outScores[currentPlayer] = -1; // so the game can continue without us
ret = scores((currentPlayer + 1) % NB_PLAYERS, 1, outScores, nbOut + 1);
}
else
{
for(int i=0; i < NB_PLAYERS; i++)
{
if (outScores[i] == 0)
{
outScores[i] = NB_PLAYERS; // set the winner
}
}
}
outScores[currentPlayer] = nbOut + 1;
ret.push_back(pair<int, int>(1,currentPlayer));
return ret;
}
if (toWrite + 1 == MAX_VALUE) // no point playing to lose, if we can avoid it
{
vector<pair<int, int>> ret;
ret = scores((currentPlayer + 1) % NB_PLAYERS, toWrite + 1, outScores, nbOut);
ret.push_back(pair<int,int>(1,currentPlayer));
return ret;
}
int scoresIfPlay1[NB_PLAYERS];
int scoresIfPlay2[NB_PLAYERS];
vector<pair<int,int>> ret1;
vector<pair<int,int>> ret2;
memcpy(scoresIfPlay1, outScores, sizeof(int) * NB_PLAYERS);
memcpy(scoresIfPlay2, outScores, sizeof(int) * NB_PLAYERS);
ret1 = scores((currentPlayer + 1) % NB_PLAYERS, toWrite + 1, scoresIfPlay1, nbOut); //recurse with both choices
ret2 = scores((currentPlayer + 1) % NB_PLAYERS, toWrite + 2, scoresIfPlay2, nbOut);
if (scoresIfPlay2[currentPlayer] > scoresIfPlay1[currentPlayer]) // pick the solution that yields the higher score
{
memcpy(outScores, scoresIfPlay2, sizeof(int) * NB_PLAYERS);
ret2.push_back(pair<int,int>(2,currentPlayer));
return ret2;
}
else
{
memcpy(outScores, scoresIfPlay1, sizeof(int) * NB_PLAYERS);
ret1.push_back(pair<int,int>(1,currentPlayer));
return ret1;
}
}
int main()
{
int outScores[NB_PLAYERS] = {0};
vector<pair<int, int>> plays = scores(0, 1, outScores, 0);
for(int i = 0; i < NB_PLAYERS; i++)
{
cout << "Player " << i << " has score " << outScores[i] << endl;
}
cout << endl;
cout << "Plays were: " << endl;
for(int i = plays.size() - 1; i >= 0; --i)
{
cout << "player " << plays[i].second << " plays " << plays[i].first << " times." << endl;
}
}
=== 旧答案 ===
如前所述,这个问题无法让您判断自己会赢还是输。为此,您必须以一种或另一种方式更改规则:由于将有 9 个失败者和 1 个获胜者,因此任何未获胜的玩家都可以改变他们的游戏方式,并且在他们仍然失败时影响谁获胜。例如。玩家 x 输了任何一种方式,但可以使玩家 y 赢或输。 x 将如何播放尚未定义。
你需要选择一个场景:
- 每个玩家都会尝试尽快消灭其他玩家,只要不让他们输。
- 或者,稍后被淘汰会产生更多积分。玩家将最大化他们的分数。
无论如何,解决方案应该比上面的更复杂。你可能想要递归
int scoreFromPosition(int player,int no_of_players,int counter)
这将返回当 no_of_player 个玩家离开时玩家 player 可以获得的最大分数,counter 当前是 counter。