zoukankan      html  css  js  c++  java
  • 求一个等差数列

    需要要一个金额递减的效果,最终的效果如下,这其实就是一个等差数列。

    我们学过的等差数列求和公式是:

    也就是首末相加乘以N再除以2.而我们得到的参数是总金额和总人数,求整个数列。我们默认最小的差值是0.01,也就是一分钱,首项是a0,那么aN=a0+(n-1)*gap代码如下:

     private decimal[] GetDeclines(decimal reward, int people, decimal min)
            {
                //需要验证min 和 gap
                //min不能大于平均值。gap可以是0,
                //求和公式 2*reward=(a0+ak)*n       k=n-1
                //people只有一人
                if (people == 1)
                    return new[] { reward };
                //min等于平均值
                if (min == (reward / people) && ((int)reward * 100 % people == 0)) return GetAverages(reward, people);
    
                var a_0a_n = 2 * reward / people;//得到首末两项的和
                var gap_n_1 = a_0a_n - 2 * min;//得到peple-1个间距的值
                var gap100 = (int)(gap_n_1 / (people - 1) * 100);//放大一百倍 确保小数
                var gap = (decimal)gap100 / 100;
                var results = new decimal[people];
            //然后逐个求出每一项的值。
                for (int i = 0; i < people; i++)
                {
                    results[i] = min + gap * (people - i - 1);
                }
                
                var sum = people * (results[0] + results[people - 1]) / 2;
                var more = reward - sum;
                results[0] = results[0] + more;
    
                return results;
            }

    关键是通过min计算出差额gap,而这个差值我们可以默认的设置为总金额的五十分之一。

    if (model.Reward >=1)
    {
      model.MinReward = model.Reward / 50;
    }

    金额不可能每次被完全分掉,这里是将多出的金额加到了的第一项里面。

     

    你会发现剩余金额其实不会随着总金额变大而变大,居然是一样的。有点意思。console代码如下:

    class Program
        {
            static void Main(string[] args)
            {
                GetDeclines(1000, 10);
                Console.Read();
            }
    
            private static decimal[] GetDeclines(decimal reward, int people)
            {
                var min=(decimal)0.01;
                if (reward > 1)
                {
                    min = reward/50;
                }
    
                //需要验证min 和 gap
                //min不能大于平均值。gap可以是0,  
                //求和公式 2*reward=(a0+ak)*n       k=n-1
                //people只有一人
                if (people == 1)
                    return new[] { reward };
                //min等于平均值
                if (min == (reward / people) && ((int)reward * 100 % people == 0)) return GetAverages(reward, people);
                var a_0a_n = 2 * reward / people;
                var gap_n_1 = a_0a_n - 2 * min;
                var gap100 = (int)(gap_n_1 / (people - 1) * 100);
                var gap = (decimal)gap100 / 100;
                var results = new decimal[people];
                Console.WriteLine("总金额{0},最小值{1},{2}个人,差额{3}", reward, min, people,gap);
    
                for (int i = 0; i < people; i++)
                {
                    results[i] = min + gap * (people - i - 1);
                    Console.WriteLine("第{0}项:{1}",i,results[i]);
                }
    
                var sum = people * (results[0] + results[people - 1]) / 2;
                var more = reward - sum;
                Console.WriteLine("剩余"+more);
                results[0] = results[0] + more;
    
                return results;
            }
    
            private static decimal[] GetAverages(decimal reward, int people)
            {
                var per = reward / people;
                var ds = new decimal[people];
                for (int i = 0; i < people; i++)
                {
                    ds[i] = per;
                }
                return ds;
            }
    
        }
    View Code
  • 相关阅读:
    Privacy Policy
    privacy
    将一个无法一次读入内存的大文件排序
    java实现二叉树的非递归遍历
    java静态方法同步问题
    关于java静态方法继承问题
    Android 代码写布局
    Android自定义ImageView实现手势放大图片的控件,无需依赖任何第三方。
    Gradle版本更换问题
    Android的AlertDialog实现圆角边框
  • 原文地址:https://www.cnblogs.com/stoneniqiu/p/6308923.html
Copyright © 2011-2022 走看看