How to Determine Cheapest Commute Ticket Combination

孤者浪人 提交于 2019-12-04 13:50:18

Hints

You can do this by solving the sub-problem:

What is the cheapest combination C[k] to cover all trips from day 0 up to day k?

To compute the answer to this sub-problem you can simply consider each of the cases of buying a ticket type. By solving the problems starting at 0 and working all the way up to 365 you are allowed to use previous results when solving a sub-problem.

For example, suppose on day 100 you need to make no trips. Then the answer will be C[99] which is the cheapest way of doing the trips on the previous days.

However, suppose on day 101 you need to make 3 trips. Then the answer for C[101] will be the cheapest of:

Buy round trip tickets today: cost 3*w+C[100]
Buy a 7 day ticket 7 days ago: cost x+C[101-7]
Buy a 30 day ticket 30 days ago: cost y+C[101-30]

When you have computed C[365] you can compare this to cost z for the all year ticket.

(If during this process you ever find yourself requiring the cost C[i] for i less than 0, the value of C[i] is 0.)

Here is my solution in python. But first, let me give some context so that the code below shall make sense.


Problem statement:

You want to buy public transport tickets for the upcoming month. You know the days on which you will be travelling. The month has 30 days and there are 3 types of tickets:

  • 1 day ticket costs P2, valid for one day only
  • 7 days ticket costs P7, valid for 7 consecutive days from day of purchase
  • 30 days ticket costs P25, valid for 30 days of the month.

Example,

month_travel_days = [1,2,4,5,7,29,30]

From the example travel days, the minimum cost is P11 by buying a 7-days ticket costing P7 and then buying separately for the remaining two days of 29th and 30th costing P4.

Solve the problem of minimizing the cost of ticket purchase given any list of travel days.


from operator import itemgetter

#travel_dates = [1,2,4,5,7,29,30]
travel_dates = [1,3,5,8,9,10]
#travel_dates = range(30)

def normalize(data):
    L = 30
    d1 = []
    for i in xrange(L):
        d1.append(1 if (i+1) in data else 0)
    return d1

def group_func(d):
    L = len(d)
    result = []
    for i in xrange(L):
        s = sum(d[i:i+7])
        result.append((i,s))
    return result

d1 = normalize(travel_dates)
mincost = 0
while True:
    a = group_func(d1)
    a.sort(key = itemgetter(1))
    m = a[-1][1]
    if m < 4:
        break
    for q in a:
        if q[1] == m:
            w = q
            break
    d1[w[0]:w[0]+7] = [0]*7
    mincost = mincost + 7 
mincost = mincost + d1.count(1) * 2
answer = min(25,mincost)
print "minimum cost = " + str(answer)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!