甚至在几天内分发物品

时间:2014-02-20 22:00:13

标签: c# algorithm distribution

我需要在固定的天数内分发剩余的项目。例如说我有197项和75天分发它们。如果我在75天内显示2个项目,那么我有47个项目未显示。如何在75天内均匀分配剩余的47个项目,这样我就可以获得2,3,3,2,3,3,2,2,3等序列,即3个均匀分布在整个展示。这就是我到目前为止所拥有的

const double num = (double)197/75;
double temp = num;
var list = new List<int>();
for (var t = 1; t <= days; t++)
{
    var intPart = int.Parse(Math.Truncate(temp).ToString());

    list.Add(intPart);

    var remainder = num - intPart;

    temp = num + remainder;
}

但我最终只显示了187个项目。我错过了10。

1 个答案:

答案 0 :(得分:3)

如AlexD所述,原始答案在某些情况下得出的结果并不理想:

int numItems = 197;
int numDays = 75;
var list = new List<int>();
for (int t = 0; t < numDays; t++)
{
    int numItemsInDay = ((t+1)*numItems+numDays/2)/numDays - (t*numItems+numDays/2)/numDays;
    list.Add(numItemsInDay);
}

这个想法是每个项目进入由itemIndex*numDays/numItems的舍入值定义的日期,您可以直接计算一天中的项目数,而无需跟踪以前的项目。


另一种方法。

要在numItems天内尽可能均匀地传播numDays个项目,您需要将这些日期分为floor(numItems/numDays)个项目以及ceil(numItems/numDays)天的跨度。项目,尽可能均匀地传播跨度。因此,可以通过递归减少跨度数的天数来解决问题。

static List<int> Spread(int numDays, int numItems)
{
    List<int> result = new List<int>();
    if (numDays <= 1)
    {
        if (numDays == 1)
            result.Add(numItems);
        return result;
    }
    int numItemsInDayLower = numItems/numDays;
    int numItemsInDayHigher = numItemsInDayLower+1;
    int numDaysHigher = numItems - numItemsInDayLower * numDays;
    int numDaysLower = numDays-numDaysHigher;
    int numSpansLower = numDaysLower > numDaysHigher ? numDaysHigher + 1 : numDaysLower;
    int numSpansHigher = numDaysHigher > numDaysLower ? numDaysLower + 1 : numDaysHigher;
    bool isStartingFromSpanLower = numDaysLower > numDaysHigher;
    List<int> spanLehgthsLower = Spread(numSpansLower, numDaysLower);
    List<int> spanLehgthsHigher = Spread(numSpansHigher, numDaysHigher);
    for (int iSpan = 0; iSpan < spanLehgthsLower.Count + spanLehgthsHigher.Count; iSpan++)
    {
        if ((iSpan % 2 == 0) == isStartingFromSpanLower)
        {
            for (int i = 0; i < spanLehgthsLower[iSpan/2]; i++)
                result.Add(numItemsInDayLower);
        }
        else
        {
            for (int i = 0; i < spanLehgthsHigher[iSpan/2]; i++)
                result.Add(numItemsInDayHigher);
        }
    }
    return result;
}