如果我有$ 1000(可变),并且我想将这笔钱分配给20个(可变)人,但不是平均分配给每个人,我想给第一个人更多,第二人称,等等。
因此,第20个人的人数最少,而第5个人的人数最多。
我将如何实现?
谢谢
编辑:
公式:
int people = 20;
float prize = 1000;
float k = (2 * prize) / ((people) * (people - 1));
float sum = 0;
for (int i = 1; i < people; ++i)
{
var personsPrize = i * k;
sum += personsPrize;
Console.WriteLine(personsPrize);
}
Console.WriteLine("sum = " + sum);
答案 0 :(得分:1)
公式是正确的,需要一点点触摸。
在从第一人称进入n-1的for内进入
int people = 20;
float prize = 1000;
float k = (2 * prize) / ((people) * (people - 1));
float sum = 0;
for (int i = 1; i < people; ++i)
{
var personsPrize = i * k;
sum += personsPrize;
Console.WriteLine(personsPrize);
}
Console.WriteLine("sum = " + sum);
答案 1 :(得分:0)
为Ensure prize pool doesn't award tied participants less than participants who scored worse添加答案
两件事
不正确,当将价格从第一人称开始向n-1 分配时,一个人没有获得奖金,正确的是从第一人称开始向n 分配。 >
带有K的有效basePrize是
k =(2 *奖金)/((人)*(人+ 1))
现在回答另一个问题:
int totalPeople = 20;
float prize = 5000;
List<int> peopleScores = new List<int>();
Random r = new Random();
for (int i = 0; i < totalPeople; ++i)
{
peopleScores.Add(r.Next(0, 100));
}
var totalPeopleWithScore = peopleScores.Where(x => x > 0).Count();
var groupedScores = peopleScores
.Where(x => x > 0)
.ToList()
.GroupBy(x => x)
.Select(grp => new
{
score = grp.Key,
peopleScores = grp.ToList()
})
.OrderBy(g => g.score)
.ToList();
var groupCount = groupedScores.Select(x => new { count = x.peopleScores.Count() }).Select(z => z.count).Count();
float basePrizeRate = 2 * prize / totalPeopleWithScore / (totalPeopleWithScore + 1);
Console.WriteLine("Base Price rate: " + basePrizeRate);
float sum = 0;
var leaderboardPosition = 0;
var totalWinners = 0;
foreach (var positionScore in groupedScores)
{
var countWinner = positionScore.peopleScores.Count();
Console.WriteLine();
Console.WriteLine($"On leaderboard position : {groupedScores.Count() - leaderboardPosition} are {countWinner} winners with score: {positionScore.score}");
float positionPrizePool = 0;
for (int i = 1; i <= positionScore.peopleScores.Count(); ++i)
{
totalWinners++;
positionPrizePool += totalWinners * basePrizeRate;
}
Console.WriteLine("Prize Pool " + positionPrizePool);
var personPoolPrize = positionPrizePool / positionScore.peopleScores.Count();
foreach (var x in positionScore.peopleScores)
{
Console.WriteLine($"Winner {totalWinners} won: {personPoolPrize}");
sum += personPoolPrize;
}
leaderboardPosition++;
}
Console.WriteLine();
Console.WriteLine("Total Prize: " + sum);
Console.WriteLine("Total Winners: " + totalPeopleWithScore);
答案 2 :(得分:0)
你欠我一杯啤酒,实际上是一杯啤酒!
使用高斯分布(N *(N + 1))/ 2,您不能在竞争者排名上有微不足道的优势,奖品会线性增加https://mathbitsnotebook.com/Algebra2/Sequences/SSGauss.html。
您需要的是呈指数增长或以固定比例分配的东西,我想用数学方法解决您的问题,所以我将使用几何级数https://mathbitsnotebook.com/Algebra2/Sequences/SSGeometric.html
在此答案之后,我将不再添加其他答案,您必须构建自己的奖池系统!
对于几何分布公式为:
rankPrize =(((1-distributionFactor)/(1-distributionFactor ^ 获胜者)* distributionFactor ^(rank-1))*奖品
其中 distributionFactor -在0到1之间
试用分配因子并为您的系统选择正确的值,我选择0.8是因为奖品之间的差距并不大!
在这里,我们拨弄链接:https://dotnetfiddle.net/qmJnYd并进行实施:
static void GaussDistributionPricePool()
{
Console.WriteLine("________________________________________________________");
Console.WriteLine("Begin Gauss distribution price pool");
int totalPeople = 20;
float prize = 5000;
List<int> peopleScores = new List<int>();
Random r = new Random();
for (int i = 0; i < totalPeople; ++i)
{
peopleScores.Add(r.Next(0, 100));
}
var totalPeopleWithScore = peopleScores.Where(x => x > 0).Count();
var groupedScores = peopleScores
.Where(x => x > 0)
.ToList()
.GroupBy(x => x)
.Select(grp => new
{
score = grp.Key,
peopleScores = grp.ToList()
})
.OrderBy(g => g.score)
.ToList();
var groupCount = groupedScores.Select(x => new { count = x.peopleScores.Count() }).Select(z => z.count).Count();
// Gauss formula. (N*(N+1))/2
// https://mathbitsnotebook.com/Algebra2/Sequences/SSGauss.html
float basePrizeRate = 2 * prize / totalPeopleWithScore / (totalPeopleWithScore + 1);
Console.WriteLine("Base Price rate: " + basePrizeRate);
float sum = 0;
var leaderboardRank = 0;
var totalWinners = 0;
foreach (var positionScore in groupedScores)
{
var countWinner = positionScore.peopleScores.Count();
Console.WriteLine();
Console.WriteLine("On leaderboard rank : " + (groupedScores.Count() - leaderboardRank) + " are " + countWinner + " winners with score: " + positionScore.score);
float positionPrizePool = 0;
for (int i = 1; i <= positionScore.peopleScores.Count(); ++i)
{
totalWinners++;
positionPrizePool += totalWinners * basePrizeRate;
}
Console.WriteLine("Prize Pool " + positionPrizePool);
var personPoolPrize = positionPrizePool / positionScore.peopleScores.Count();
foreach (var x in positionScore.peopleScores)
{
Console.WriteLine("Winner " + totalWinners + " won: " + personPoolPrize);
sum += personPoolPrize;
}
leaderboardRank++;
}
Console.WriteLine();
Console.WriteLine("Total Prize: " + sum);
Console.WriteLine("Total Winners: " + totalPeopleWithScore);
Console.WriteLine("End Gauss distribution price pool");
Console.WriteLine("________________________________________________________");
}