dynamic-programming
Stångskärning
Sök…
Skär stången för att få maximal vinst
Får en stav med längd n tum och en matris med längd m av priser som innehåller priser för alla delar av storlek mindre än n. Vi måste hitta det maximala värdet som kan erhållas genom att skära upp stången och sälja bitarna. Om till exempel stavens längd är 8 och värdena för olika delar anges enligt följande är det maximala erhållna värdet 22 .
+---+---+---+---+---+---+---+---+
(price)| 1 | 5 | 8 | 9 | 10| 17| 17| 20|
+---+---+---+---+---+---+---+---+
Vi använder en 2D-array dp [m] [n + 1] där n är längden på stången och m är längden på prisuppsättningen. För vårt exempel behöver vi dp [8] [9] . Här kommer dp [i] [j] att beteckna det högsta priset genom att sälja stången med längd j. Vi kan ha det maximala värdet på längden j som helhet eller vi kunde ha brutit längden för att maximera vinsten.
Först, för den 0: e kolumnen, kommer den inte att bidra med något, varför alla värden markeras som 0. Så alla värden för den 0: e kolumnen kommer att vara 0. För dp [0] [1] , vad är det maximala värdet vi kan få genom säljer stav med längd 1.Det kommer att vara 1.Simlar för stav med längd 2 dp [0] [2] kan vi ha 2 (1 + 1). Detta fortsätter till dp [0] [8]. Så efter den första iterationen vår dp [] -uppsättning kommer att se ut.
+---+---+---+---+---+---+---+---+---+
(price)| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
+---+---+---+---+---+---+---+---+---+
(1) 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 |
+---+---+---+---+---+---+---+---+---+
(5) 2 | 0 | | | | | | | | |
+---+---+---+---+---+---+---+---+---+
(8) 3 | 0 | | | | | | | | |
+---+---+---+---+---+---+---+---+---+
(9) 4 | 0 | | | | | | | | |
+---+---+---+---+---+---+---+---+---+
(10) 5 | 0 | | | | | | | | |
+---+---+---+---+---+---+---+---+---+
(17) 6 | 0 | | | | | | | | |
+---+---+---+---+---+---+---+---+---+
(17) 7 | 0 | | | | | | | | |
+---+---+---+---+---+---+---+---+---+
(20) 8 | 0 | | | | | | | | |
+---+---+---+---+---+---+---+---+---+
För dp [2] [2] måste vi fråga oss själva att vad som är det bästa jag kan få om jag bryter stången i två delar (1,1) eller tar stången som helhet (längd = 2). Vi kan se att om jag bryter stången i två delar är den maximala vinsten jag kan göra 2 och om jag har stången som helhet så kan jag sälja den för 5.Efter andra iterationen kommer dp [] -fältet att se ut:
+---+---+---+---+---+---+---+---+---+
(price)| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
+---+---+---+---+---+---+---+---+---+
(1) 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 |
+---+---+---+---+---+---+---+---+---+
(5) 2 | 0 | 1 | 5 | 6 | 10| 11| 15| 16| 20|
+---+---+---+---+---+---+---+---+---+
(8) 3 | 0 | | | | | | | | |
+---+---+---+---+---+---+---+---+---+
(9) 4 | 0 | | | | | | | | |
+---+---+---+---+---+---+---+---+---+
(10) 5 | 0 | | | | | | | | |
+---+---+---+---+---+---+---+---+---+
(17) 6 | 0 | | | | | | | | |
+---+---+---+---+---+---+---+---+---+
(17) 7 | 0 | | | | | | | | |
+---+---+---+---+---+---+---+---+---+
(20) 8 | 0 | | | | | | | | |
+---+---+---+---+---+---+---+---+---+
Så för att beräkna dp [i] [j] kommer vår formel att se ut:
if j>=i
dp[i][j] = Max(dp[i-1][j], price[i]+arr[i][j-i]);
else
dp[i][j] = dp[i-1][j];
Efter den sista iterationen kommer vår dp [] -serie att se ut
+---+---+---+---+---+---+---+---+---+
(price)| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
+---+---+---+---+---+---+---+---+---+
(1) 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 |
+---+---+---+---+---+---+---+---+---+
(5) 2 | 0 | 1 | 5 | 6 | 10| 11| 15| 16| 20|
+---+---+---+---+---+---+---+---+---+
(8) 3 | 0 | 1 | 5 | 8 | 10| 13| 16| 18| 21|
+---+---+---+---+---+---+---+---+---+
(9) 4 | 0 | 1 | 5 | 8 | 10| 13| 16| 18| 21|
+---+---+---+---+---+---+---+---+---+
(10) 5 | 0 | 1 | 5 | 8 | 10| 13| 16| 18| 21|
+---+---+---+---+---+---+---+---+---+
(17) 6 | 0 | 1 | 5 | 8 | 10| 13| 17| 18| 22|
+---+---+---+---+---+---+---+---+---+
(17) 7 | 0 | 1 | 5 | 8 | 10| 13| 17| 18| 22|
+---+---+---+---+---+---+---+---+---+
(20) 8 | 0 | 1 | 5 | 8 | 10| 13| 17| 18| 22|
+---+---+---+---+---+---+---+---+---+
Vi kommer att få resultatet vid dp [n] [m + 1] .
Implementering i Java
public int getMaximumPrice(int price[],int n){
int arr[][] = new int[n][price.length+1];
for(int i=0;i<n;i++){
for(int j=0;j<price.length+1;j++){
if(j==0 || i==0)
arr[i][j] = 0;
else if(j>=i){
arr[i][j] = Math.max(arr[i-1][j], price[i-1]+arr[i][j-i]);
}else{
arr[i][j] = arr[i-1][j];
}
}
}
return arr[n-1][price.length];
}
Tidskomplexitet
O(n^2)