1+ package DynamicProgramming ;
2+
3+ /**
4+ * Imagine you have a collection of N wines placed next to each other on the
5+ * shelf. The price of ith wine is pi(Prices of different wines are different).
6+ * Because wine gets better every year supposing today is year 1, on year y the
7+ * price would be y*pi i.e y times the value of the initial year. You want to
8+ * sell all wines but you have to sell one wine per year. One more constraint on
9+ * each year you are allowed to sell either leftmost or rightmost wine on the
10+ * shelf. You are not allowed to reorder. You have to find the maximum profit
11+ **/
12+
13+ public class WineProblem {
14+
15+ // Method 1: Using Recursion
16+ // Time Complexity=0(2^N) Space Complexity=Recursion extra space
17+ public static int WPRecursion (int [] arr , int si , int ei ) {
18+ int n = arr .length ;
19+ int year = (n - (ei - si + 1 )) + 1 ;
20+ if (si == ei ) {
21+ return arr [si ] * year ;
22+ }
23+
24+ int start = WPRecursion (arr , si + 1 , ei ) + arr [si ] * year ;
25+ int end = WPRecursion (arr , si , ei - 1 ) + arr [ei ] * year ;
26+
27+ int ans = Math .max (start , end );
28+
29+ return ans ;
30+ }
31+
32+ // Method 2: Top-Down DP(Memoization)
33+ // Time Complexity=0(N*N) Space Complexity=0(N*N)+Recursion extra space
34+ public static int WPTD (int [] arr , int si , int ei , int [][] strg ) {
35+ int n = arr .length ;
36+ int year = (n - (ei - si + 1 )) + 1 ;
37+ if (si == ei ) {
38+ return arr [si ] * year ;
39+ }
40+
41+ if (strg [si ][ei ] != 0 ) {
42+ return strg [si ][ei ];
43+ }
44+ int start = WPTD (arr , si + 1 , ei , strg ) + arr [si ] * year ;
45+ int end = WPTD (arr , si , ei - 1 , strg ) + arr [ei ] * year ;
46+
47+ int ans = Math .max (start , end );
48+
49+ strg [si ][ei ] = ans ;
50+
51+ return ans ;
52+ }
53+
54+ // Method 3: Bottom-Up DP(Tabulation)
55+ // Time Complexity=0(N*N/2)->0(N*N) Space Complexity=0(N*N)
56+ public static int WPBU (int [] arr ) {
57+ int n = arr .length ;
58+ int [][] strg = new int [n ][n ];
59+
60+ for (int slide = 0 ; slide <= n - 1 ; slide ++) {
61+ for (int si = 0 ; si <= n - slide - 1 ; si ++) {
62+ int ei = si + slide ;
63+ int year = (n - (ei - si + 1 )) + 1 ;
64+ if (si == ei ) {
65+ strg [si ][ei ] = arr [si ] * year ;
66+ } else {
67+ int start = strg [si + 1 ][ei ] + arr [si ] * year ;
68+ int end = strg [si ][ei - 1 ] + arr [ei ] * year ;
69+
70+ strg [si ][ei ] = Math .max (start , end );
71+
72+ }
73+ }
74+ }
75+ return strg [0 ][n - 1 ];
76+ }
77+
78+ public static void main (String [] args ) {
79+ int [] arr = { 2 , 3 , 5 , 1 , 4 };
80+ System .out .println ("Method 1: " + WPRecursion (arr , 0 , arr .length - 1 ));
81+ System .out .println ("Method 2: " + WPTD (arr , 0 , arr .length - 1 , new int [arr .length ][arr .length ]));
82+ System .out .println ("Method 3: " + WPBU (arr ));
83+
84+ }
85+
86+ }
87+ // Memoization vs Tabulation : https://www.geeksforgeeks.org/tabulation-vs-memoization/
88+ // Question Link : https://www.geeksforgeeks.org/maximum-profit-sale-wines/
0 commit comments