Find the cheapest price for X number of days

I have a technical problem for you regarding the algorithm.

Suppose I have this list of days and prices:

        List<ReservationPrice> prices = new List<ReservationPrice>();
        prices.Add(new ReservationPrice { NumberOfDays = 1, Price = 1000 });
        prices.Add(new ReservationPrice { NumberOfDays = 2, Price = 1200 });
        prices.Add(new ReservationPrice { NumberOfDays = 3, Price = 2500 });
        prices.Add(new ReservationPrice { NumberOfDays = 4, Price = 3100 });
        prices.Add(new ReservationPrice { NumberOfDays = 7, Price = 4000 });

What I would like to do now is:

give me the best price from the list based on few days.

So, if you ask for 3 days, the best price from the list is from one child (1000) and two (1200), but, of course, there are different combinations that you will have to try first. What would be the algorithm that found the best price from this list?

Thank!

+3
source share
3 answers

wiki, , np, , . , , "" .

3 4, 1 + 2 2 + 2. ( )

3 , , , ...

( 30 , 30 x 15 x 4 , .)

WizardOfOdds:

0-1 , ...

( "" "0-1 " " ", , , " ", " " ..).

, , 7 , :

7 x 1 0/1?

3x 2 0/1?

2x 3 0/1?

1x 4 0/1?

, , /

" ", "", ""...

0

.

:

Let S[i] = minimum sum obtainable for days = i, initialized to infinite at first
S[0] = 0
for (int i = 0; i < prices.Count; ++i)
{
    for (int j = MAX_DAYS; j >= prices[i].days; --j)
        S[j] = min(S[j], S[j - prices[i].days] + prices[i].price);
}

S . #. , .

class Program
{
    static void Main()
    {
        List<ReservationPrice> prices = new List<ReservationPrice>();
        prices.Add(new ReservationPrice { NumberOfDays = 1, Price = 1000 });
        prices.Add(new ReservationPrice { NumberOfDays = 2, Price = 1200 });
        prices.Add(new ReservationPrice { NumberOfDays = 3, Price = 2500 });
        prices.Add(new ReservationPrice { NumberOfDays = 4, Price = 3100 });
        prices.Add(new ReservationPrice { NumberOfDays = 7, Price = 4000 });

        DaysMinSum.Precompute(prices);
        Console.WriteLine(DaysMinSum.GetAnswer(5));
        Console.WriteLine(DaysMinSum.GetAnswer(4));
        Console.WriteLine(DaysMinSum.GetAnswer(7));
        Console.WriteLine(DaysMinSum.GetAnswer(6));
        Console.WriteLine(DaysMinSum.GetAnswer(100));
        Console.WriteLine(DaysMinSum.GetAnswer(3));
    }
}

static class DaysMinSum
{
    private static Dictionary<int, int> S = new Dictionary<int, int>();

    public static int GetAnswer(int numDays)
    {
        if (S.ContainsKey(numDays))
        {
            return S[numDays];
        }
        else
        {
            return -1;
        }
    }

    public static void Precompute(List<ReservationPrice> prices)
    {
        S.Clear();
        int maxDays = 0;

        for (int i = 0; i < prices.Count; ++i)
        {
            maxDays += prices[i].NumberOfDays;
        }

        for (int i = 0; i <= maxDays; ++i)
        {
            S.Add(i, 1 << 30);
        }

        S[0] = 0;
        for (int i = 0; i < prices.Count; ++i)
        {
            for (int j = maxDays; j >= prices[i].NumberOfDays; --j)
            {
                S[j] = Math.Min(S[j], S[j - prices[i].NumberOfDays] + prices[i].Price);
            }
        }
    }
}

class ReservationPrice
{
    public int NumberOfDays { get; set; }
    public int Price { get; set; }
}
0

, , ( , 3- 4- ).

, . ...

Days    Average
----    -------
1       1000
2       600
3       833
4       775
7       571

, . , , X (, ), 1- 1301 3- , 4- - , ). .

Days    Average
----    -------
1       1000
2       600
3       833      removed
4       775      removed
7       571

Now that you are backing up, sort by the number of days that are coming down, and create a general reservation by subtracting the maximum possible reservation from the desired number of days until you fill it. Thus, a reservation for 11 days will be 7 days and two 2 days; 10-day will be 7-day, 2-day, and 1-day.

0
source

Source: https://habr.com/ru/post/1743818/


All Articles