class: center, title-slide
## CSCI-UA 480: APS ## Algorithmic Problem Solving
## Divide and Conquer .author[ Instructor: Joanna Klukowska
] .license[ Copyright 2020 Joanna Klukowska. Unless noted otherwise all content is released under a
[Creative Commons Attribution-ShareAlike 4.0 International License](https://creativecommons.org/licenses/by-sa/4.0/).
Background image by Stewart Weiss
] --- layout:true template: default name: section class: inverse, middle, center --- layout:true template: default name: challenge class: challenge --- layout:true template: default name: poll class: inverse, full-height, center, middle --- layout:true template: default name: breakout class: breakout --- layout:true template:default name:slide class: slide .bottom-left[© Joanna Klukowska. CC-BY-SA.] --- ## Divide and Conquer - solving problems by _dividing_ them into smaller/simpler problems and then _conquering_ the subproblems - general approach: - divide the given problem into sub-problems (often using halves) - find solutions to the sub-problems (often by following the same divide and conquer approach) - combine the solutions of sub-problems into a solution for the given problem - examples - quicksort, mergesort - binary search - decrease and conquer - a version of divide and conquer algorithms in which only one sub-problem needs to be solved (as in binary search or quick-select) --- template: challenge ## Challenge: Paying Off a Loan You use a bank loan to buy a car. You need to pay off the loan by paying $d$ dollars for $m$ months. The original value of the car is $v$ and the bank charges the interest rate of $i%$ for any unpaid amount at the end of each month. Given the values for $v$, $i$ and $m$ figure out what $d$ needs to be. Determine $d$ with two digits after the decimal point. -- __Solution using a bisection method__ - we want $d$ in a particular given range [a,b] = [0.0, $v\times(1+i/100)$] - we start with an estimate for $d$ as $\dfrac{a+b}{2}$ - if the result is that we overpay, then try to decrease $d$, otherwise, increase $d$ ---
a | b | d | estimate | action ---|---|---|---|--- 0.010000|1000.000000|500.005000|underpaid|increase d 500.005000|1000.000000|750.002500|overpaid|decrease d 500.005000|750.002500|625.003750|overpaid|decrease d 500.005000|625.003750|562.504375|overpaid|decrease d 500.005000|562.504375|531.254688|overpaid|decrease d 500.005000|531.254688|515.629844|underpaid|increase d 515.629844|531.254688|523.442266|underpaid|increase d 523.442266|531.254688|527.348477|overpaid|decrease d 523.442266|527.348477|525.395371|overpaid|decrease d 523.442266|525.395371|524.418818|overpaid|decrease d 523.442266|524.418818|523.930542|overpaid|decrease d 523.442266|523.930542|523.686404|underpaid|increase d 523.686404|523.930542|523.808473|underpaid|increase d 523.808473|523.930542|523.869507|overpaid|decrease d 523.808473|523.869507|523.838990|overpaid|decrease d 523.808473|523.838990|523.823732|overpaid|decrease d 523.808473|523.823732|523.816102|overpaid|decrease d 523.808473|523.816102|523.812288|overpaid|decrease d 523.808473|523.812288|523.810380|overpaid|decrease d 523.808473|523.810380|523.809427|done --- ```C++ int m, x; double value, i; scanf ("%lf %lf %d", &value, &i, &m); double a = 0.01, b = (1+1/100)*value; double d = (a+b)/2; double paid , owed ; do { paid = 0.0, owed = value; for (int month = 1; month <= m; month++) { paid += d; owed -= d; owed *= (1+i/100); } printf("%f\t%f\t%f", a, b, d); if (fabs(0.0 - owed) < 0.001){ printf("\tdone\n"); } else if ( owed < 0) { b = d; printf ("\toverpaid\tdecrease d\n"); } else {// ( owed > 0) a = d; printf ("\tunderpaid\tincrease d\n"); } d = (a+b)/2; } while (fabs(0.0 - owed) >= 0.001 ) ; ``` --- ## Spending ALL the Money Jeff likes to read books. He also does not like to have any money. Every week he receives a check from his parents and he is determined to spend it all on books that he can read that week. He also knows that he does not have time to read more than two books in a given week. With these strange idea, Jeff needs to figure out each week which two books he should buy so that he spends all the money that he has that week. __Input__:
Each test case starts with 2 <= N <= 1000 which is the number of books he can chose from. Next line has the N book prices. The cost of a book is no more than 1,000,001. The third line has an integer M representing the amount of money that Jeff's parents sent him that week. __Output__:
For each test case you must print a message: "Jeff should buy books whose prices are i and j.", where i and j are the prices of the books whose sum is equal to M (exactly) and i <= j.
It is always possible to pick two different books whose prices add up to M.
If tehre are more than one such options, you should report on the pair for which the difference between j and i is the smallest. --- ## Spending ALL the Money Jeff likes to read books. He also does not like to have any money. Every week he receives a check from his parents and he is determined to spend it all on books that he can read that week. He also knows that he does not have time to read more than two books in a given week. With these strange idea, Jeff needs to figure out each week which two books he should buy so that he spend exactly all the money that he has that week. __Example 1__:
``` Input: 2 40 40 80 Output: Jeff should byu books whose prices are 40 and 40. ``` __Example 2__:
``` Input: 5 10 2 6 8 4 10 Output: Jeff should buy books whose prices are 4 and 6. ``` --- --- ---