为锦标赛系统分发奖品

时间:2010-08-04 19:30:27

标签: c++ algorithm math

我正在寻找一种在x个单位之间分配数字的方法。我甚至不知道怎么说这些话所以我举一个例子:

有一场锦标赛,奖金总额为1000美元。我希望前20名获胜者/参赛者能够赢得一些东西。我需要一个数学算法/公式,这些算法/公式会在这些参与者之间产生差异,这使我有能力控制分配中的某些其他因素。

例如,我希望排名第一的获胜者获得300美元。排名第二的获胜者将获得较小的比例。总分配必须给每个人一些东西,直到排名第20的获胜者(最后一个)至少获得X $ X $是我想要控制的另一个因素。

有什么想法吗?此问题是否有名称(名称是什么)?任何代码示例?

编辑#1 - 我的第一个提案

#include <conio.h>
#include <vector>

#define TOTAL                       100
#define WINNERS                     15
#define FIRST_WINNER_PERCENTAGE     0.30

void distribute_1(::std::vector<double> * const prizes)
{
    prizes->clear();

    double total = TOTAL;
    double winning_percentage = FIRST_WINNER_PERCENTAGE;
    double slope = 0.5;
    int winners = WINNERS;

    double winning = 0;
    for(int i = 0; i < winners; i++, total -= winning, winning_percentage /= 2)
    {
        winning = total * winning_percentage;
        prizes->push_back(winning);
    }
}
void distribute_2(::std::vector<double> * const prizes)
{
    prizes->clear();

    double total = TOTAL;
    double winning_percentage = FIRST_WINNER_PERCENTAGE;
    double slope = 0.5;
    int winners = WINNERS;

    double winning = 0;
    for(int i = 0; i < winners; i++, total -= winning/*, winning_percentage /= 2*/)
    {
        winning = total * winning_percentage;
        prizes->push_back(winning);
    }
}
void distribute_3(::std::vector<double> * const prizes)
{
    prizes->clear();

    double total = TOTAL;
    double winning_percentage = FIRST_WINNER_PERCENTAGE;
    double slope = 0.0005;
    int winners = WINNERS;

    double winning = 0;
    for(int i = 0; i < winners; i++, total -= winning, winning_percentage -= slope)
    {
        winning = total * winning_percentage;
        prizes->push_back(winning);
    }
}
void distribute_4(::std::vector<double> * const prizes)
{
    prizes->clear();

    double total = TOTAL;
    double winning_percentage = FIRST_WINNER_PERCENTAGE;
    double slope = 1 / WINNERS;
    int winners = WINNERS;

    double winning = 0;
    for(int i = 0; i < winners; i++, total -= winning, winning_percentage -= slope)
    {
        winning = total * winning_percentage;
        prizes->push_back(winning);
    }
}

void main()
{
    ::std::vector<double> prizes;

    distribute_1(&prizes);
    distribute_2(&prizes);
    distribute_3(&prizes);
    distribute_4(&prizes);

    double total_granted = 0;
    for(int i = 0; i < WINNERS; i++)
    {
        total_granted += prizes[i];
        printf("%lf\n", prizes[i]);
    }
    printf("-\n%lf\n", total_granted);

    _getch();
}

这是我能达到的目标。例如,如果你将'WINNERS'设置为5,那么算法就不会达到“TOTAL”数量(本例中为100)或更接近(我总共得到83)

Cristy的解决方案

#include <conio.h>
#include<iostream>
//using arithmetic progression
using namespace std;
int i;
float ratio;
float first_prize;
float s;
int main()
{
    float money=1000;
    const int total_prizes =        10;
    float last_prize =              99;
    float prizes[total_prizes+1];

    /**/first_prize=2*money/total_prizes-last_prize; //last member of the progresion
    ratio=(first_prize-last_prize)/(total_prizes-1);
    prizes[total_prizes]=last_prize;
    for(i=total_prizes-1;i>=1;i--){
       prizes[i]=prizes[i+1]+ratio;
       money-=prizes[i];
    }
    for(i=1;i<=total_prizes;i++){
        printf("%d) %.2f\n",i,prizes[i]);
        s+=prizes[i];
    }
    printf("TOTAL SUM:%.2f\n",s);
    printf("Ratio: %.2f", ratio);
    _getch();
}

6 个答案:

答案 0 :(得分:3)

现在是凌晨1点15分,我正在解决数学问题:)) 使用算术级数。
我完全使用了定义,因此您可以轻松地更改它们。

#include<iostream>
//using arithmetic progression
using namespace std;
FILE *g=fopen("output.out","w");
#define last_prize 10
#define total_prizes 20
int i;
float prizes[total_prizes+1];
float money=1000;
float ratio;
float first_prize;
float s;
//a1=last_prize
//an=first_prize
int main(){
 first_prize=2*money/total_prizes+last_prize; //last member of the progresion
 ratio=(first_prize-last_prize)/(total_prizes-1);
 prizes[total_prizes]=last_prize;
    for(i=total_prizes-1;i>=1;i--)
       prizes[i]=prizes[i+1]+ratio;
 for(i=1;i<=total_prizes;i++){
  fprintf(g,"%d) %.2f\n",i,prizes[i]);
  s+=prizes[i];
 }
 fprintf(g,"TOTAL SUM:%.2f",s);
return 0;
}

输出:

1) 90.00
2) 85.79
3) 81.58
4) 77.37
5) 73.16
6) 68.95
7) 64.74
8) 60.53
9) 56.32
10) 52.11
11) 47.89
12) 43.68
13) 39.47
14) 35.26
15) 31.05
16) 26.84
17) 22.63
18) 18.42
19) 14.21
20) 10.00
TOTAL SUM:1000.00

正如您所看到的,他们总结为1000.00 $:D

其他结果:
INPUT:

#define last_prize 30
#define total_prizes 5

输出:

1) 370.00
2) 285.00
3) 200.00
4) 115.00
5) 30.00
TOTAL SUM:1000.00

答案 1 :(得分:2)

你可以制作一个简单的公式,如。

#include<iostream>
using namespace std;
FILE *g=fopen("output.out","w");
int i;
int prizes[21];
int money=1000;
int main(){
    for(i=1;i<=20;i++){
       prizes[i]=(float)(15+(20-i))/100*money;
       money-=prizes[i];
    fprintf(g,"%d) %d\n",i,prizes[i]);
      }
return 0;
}

这将输出:

1) 340
2) 217
3) 141
4) 93
5) 62
6) 42
7) 29
8) 20
9) 14
10) 10
11) 7
12) 5
13) 4
14) 3
15) 2
16) 2
17) 1
18) 1
19) 1
20) 0

但您可以将值更改为您想要的任何内容:) 这只是一种快速而简单的方法。

该算法的起始特征是:
一等奖:30%来自所有钱(1000美元)= ~330美元 二等奖:其余30%(670美元)= ~201 三等奖:其余30%......等等 如果用20代替(15 +(20-i)),你可以得到这个输出:
只需更改该值即可获得不同的结果。

1) 200
2) 160
3) 128
4) 102
5) 82
6) 65
7) 52
8) 42
9) 33
10) 27
11) 21
12) 17
13) 14
14) 11
15) 9
16) 7
17) 6
18) 4
19) 4
20) 3

修改 还有一件事。在使用该算法分割所有资金之后,可能仍然存在一些资金(因为最后一个从其余部分获得x%)。你可以把剩下的东西添加到第一个地方......

答案 2 :(得分:1)

我有一个游泳池的问题 - 我希望3个级别的个人奖品具有相同的相对比率(70%/ 20%/ 10%),但我认识到关系的可能性,所以我不得不考虑到这一点。我不想只是分开底池然后奖励奖品,因为你可能最终获得第二名并且个人第二名获胜者获得的奖金低于第三名。

P(i)=奖品的大小 N(i)=获胜者人数

1)总和(在i上)P(i)* N(i)= $ 1000

2)P(1)/ P(2)= 70/20

3)P(2)/ P(3)= 20/10

就我而言,3个未知数中的3个方程 - 我解决了这个问题以得到一个独特的解决方案。

对于您的示例P(1)= $ 300。我只是指定连续的奖金比例并解决线性方程组。

考虑在最近的英国公开锦标赛上寻找here高尔夫奖项的分布。我不是说PGA可以比这个网站上的人才做得更好,但它可以证明你的问题在行动。

答案 3 :(得分:0)

假设总金额M,您希望在n个池中分配,这样第一个人将比第二个人获得k倍,第二个人获得的k次数超过第三个,依此类推。假设最后一个获得x金额,那么

x + k * x + k ^ 2 * x ... k ^(n-1)* x = M. x(k ^ n-1)/(k-1)= M

根据你选择和分配金钱的价值从这个等式求解x: - )

答案 4 :(得分:0)

克里斯蒂第一行的公式是错误的。 first_prize = 2 *钱/ total_prizes + last_prize; 它应该是first_prize = 2 * money / total_prizes - last_prize;

这是我在python中的解决方案,这将为最佳赢家增加剩余金额。

starting_amount = (((winnings * 2) / float(no_of_winners)) - last_amount)

difference = (last_amount - starting_amount) / float(no_of_winners - 1)
for rank in range(1, no_of_winners + 1):
    reward = starting_amount + difference * (rank - 1) 
    reward = round_amount(reward)
    winnings -= reward
    winning_amount[rank] = reward

residual_winnings = winnings
residual_shares = {1: 0.5, 2: 0.3, 3: 0.2} 

if no_of_winners < 3: 
    winning_amount[1] += residual_winnings
else:
    for rank in residual_shares:
        reward = residual_winnings * residual_shares[rank]
        reward = round_amount(reward)
        winning_amount[rank] += reward

答案 5 :(得分:0)

我花了几个小时试图想出一种分发奖品的算法。这是我根据我在各种论坛上看到的内容的解决方案。这段代码是用 Ruby 编写的。这对我很有用。

def self.get_prize_array(money,total_prizes)
    prizes = []  
    p = 0.7 # tweek this for distribution of payout 
    n = total_prizes
    l = money
    (1..total_prizes).each do |r|
       prizes[r-1] = ((1 - p) / (1 - p**n) * p**(r - 1)) * l   # p**n is p to the nth power
    end   
    return prizes
  end