Difficult dynamic planning problems-payment problems, arbitrary nominal value, can be changed to zero

Source: Internet
Author: User

When buying things in a supermarket, you often encounter payment and money-seeking problems.

In general, the nominal value of our currency is also 100, 50, 20, 10, 5, 1, 0.5, 0.1, which are basically multiples of 1 or 5. Q: How many bills do I have to pay at least? This problem is relatively easy, as long as the payment from large to small.

In addition, the number of banknotes that can be changed is also counted in the total number of banknotes, which minimizes the total number of banknotes. For example, if you want to pay 98 yuan, you only need to pay 100 yuan to find 1 + 1 yuan, with a total of three items, instead of 50 + 20 + 10 + 5 + 1 + 1 + 1 7. This problem is a little difficult. You can think about it.

I did not carefully read the questions on a python website today. So it took a day to solve this problem:

Given a group of banknotes with any nominal value and the amount of money to be paid, you can find the change (the number of banknotes to be changed is also included in the number of banknotes used ), how many banknotes can be used at least?

The nominal value of the banknote used for the change is also in the given nominal value. For example, if the given nominal value is [100, 99] and the payment is 50 yuan, the best solution is to pay 50 RMB for 99 yuan and 49 RMB for 100 yuan. A total of 10 images are used.

---------------- The following spoiler answers --------------------------------

I found that the code I wrote at the beginning was basically correct. The difficulty is to determine the maximum roof and whether the payment can be made.

The minimum price that a bird can pay for a given nominal value is determined by their public maximum appointment number! In this way, you can know whether to pay and the maximum number of payment items (roof) in advance to facilitate subsequent searches. It's really easy to understand.

def gcd(a,b):while b!=0:a,b = b,a%breturn adef checkio(data):'return minimal amount of used coins and notes.'d = {}l, dest = data# if l has float, amplify the numbers to integerl_dot = [len(str(i)) -1 - str(i).find('.') for i in l if int(i)!=i]if len(l_dot) != 0:l = [i*10**max(l_dot) for i in l]dest *= 10**max(l_dot)# use gcd, we can calc the minimal value that can be paid.mini = reduce(gcd, l)if dest % mini != 0:# This value can't be paid.return 0roof = dest / minifor i in l:d[i] = 1cur = 0while True:cur += 1for cur1 in xrange(1, cur+1):for i in sorted(d.keys()):if d[i] >= roof:continuefor j in l:if i + j == cur1 and ( not d.has_key(cur1) or d[cur1]>d[i]+1 ):d[cur1] = d[i] + 1if cur1 == dest and ( d[cur1]<roof ):roof = d[cur1]for cur2 in xrange(cur, 0, -1):for i in sorted(d.keys(), reverse=True):if d[i] >= roof:continuefor j in l:if i - j == cur2 and ( not d.has_key(cur2) or d[cur2]>d[i]+1 ):d[cur2] = d[i] + 1if cur2 == dest and ( d[cur2]<roof ):roof = d[cur2]if d.has_key(cur) and d[cur]>=roof:breakprint dprint d[dest]return d[dest]if __name__ == '__main__':#You give 100$ and get in change 1$assert checkio([[100,50,20,10,5,1],99]) == 2, 'First'#You can't give change#assert checkio([[50,20,5],41]) == 0, 'Second'# You give 2 times 20 and  1 or 50 and 1 and get 10 in change.#Other combinations are posible but you will use more then 3 notes.assert checkio([[50,20,10,5,1,0.5],41])==3, 'Third'assert checkio([[50, 20, 10, 5, 1], 78])  == 5 , 'Fourth'assert checkio([[1], 78])  == 78 , 'Fifth'checkio([[7,11,13], 1])checkio([[100,98], 1])

Leave the remaining work to the future ~~ :

Since we know the minimum price that can be composed of a given nominal value, we can calculate the "Basic denomination" by searching, and then use the "Basic denomination" for the next step: Use a forward search to pay the price, you do not need to consider changing the value to zero.

In this way, the main loop will be much simpler.

Come on ~

---------------- The following are previous mistakes: mental journey ------------------------

At first, I thought this question was very difficult. On the basis of the "package installation problem" (see the previous blog titled "DP is King"), I kept searching forward and backward in two directions, which was very complicated, and it seems that the results are not correct yet.

Later, I was inspired to think about such a subproblem.

Sub-question: Can I theoretically pay for a series of banknotes and prices?

Why can't I pay? It is because you may not be able to pay for it no matter how you change the value. For example, if the given nominal value is an even number like 2, 10, and 20, and the payment is an odd number, you will be pitted :)

I thought it was wrong. The whole thing is wrong {

(I had an incorrect idea. I corrected it when I was writing this blog. In the past, I thought that the price could be divisible by the "minimum face value", and the price would be paid. Otherwise, the price would not work. The "minimum nominal value" is the minimum nominal value that can be obtained through the combination of addition and subtraction. For example, in the above example [100], because-99 = 1, all positive integers can actually be paid.

I found it wrong when I was counting [7, 11, 13. [, 13] whether the minimum denomination can be paid is 2 (here it is still wrong, you can pay 1 yuan, you only need to pay 7 + 7, find 13 yuan ), but it can be used to pay 7, 11, 13, 9, 15 and so on. Try it.

}

()









Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.