public class RodCutting {
public static int CUT_ROD(int[] p, int n){
if(n == 0){
return 0;
}
int q = Integer.MIN_VALUE;
for(int i = 1; i <= n; i++){
q = Math.max(q, p[i] + CUT_ROD(p, n - i));
}
return q;
}
public static int MEMOIZED_CUT_ROD(int[] p, int n){
int[] r = new int[n+1];
for(int i = 0; i <= n; i++){
r[i] = Integer.MIN_VALUE;
}
return MEMOIZED_CUT_ROD_AUX(p, n, r);
}
public static int MEMOIZED_CUT_ROD_AUX(int[] p, int n, int[] r){
if(r[n] >= 0){
return r[n];
}
int q;
if(n == 0){
q = 0;
}else{
q = Integer.MIN_VALUE;
for(int i = 1; i <= n; i++){
q = Math.max(q, p[i] + MEMOIZED_CUT_ROD_AUX(p, n - i, r));
}
}
r[n] = q;
return q;
}
public static int BOTTOM_UP_CUT_ROD(int[] p, int n){
int[] r = new int[n+1];
r[0] = 0;
for(int j = 1; j <= n; j++){
int q = Integer.MIN_VALUE;
for(int i = 1; i <= j; i++){
q = Math.max(q, p[i] + r[j - i]);
}
r[j] = q;
}
return r[n];
}
public static long CUT_ROD_TIMING(int[] p, int n){
Timer timer = new Timer();
timer.start();
int r_n = CUT_ROD(p, n);
timer.end();
return timer.time();
}
public static long MEMOIZED_CUT_ROD_TIMING(int[] p, int n){
Timer timer = new Timer();
timer.start();
int r_n = MEMOIZED_CUT_ROD(p, n);
timer.end();
return timer.time();
}
public static long BOTTOM_UP_CUT_ROD_TIMING(int[] p, int n){
Timer timer = new Timer();
timer.start();
int r_n = BOTTOM_UP_CUT_ROD(p, n);
timer.end();
return timer.time();
}
public static void main(String[] args){
int[] p = new int[]{0,1,5,8,9,10,17,17,20,24,30};
int n = Integer.parseInt(args[0]);
if(n >= p.length){
int[] pPrime = new int[n + 1];
int i = 0;
for(i = 0; i < p.length; i++){
pPrime[i] = p[i];
}
for(; i <= n; i++){
pPrime[i] = p[p.length - 1];
}
p = pPrime;
}
long elapsed = -1;
int maxRevenue = -1;
System.err.println("n = "+n);
elapsed = CUT_ROD_TIMING(p, n);
System.err.println(elapsed + "\tnanoseconds CUT_ROD() - Recursive top-down implementation");
elapsed = MEMOIZED_CUT_ROD_TIMING(p, n);
System.err.println(elapsed + "\tnanoseconds MEMOIZED_CUT_ROD() - Top-down with memoization implementation");
elapsed = BOTTOM_UP_CUT_ROD_TIMING(p, n);
System.err.println(elapsed + "\tnanoseconds BOTTOM_UP_CUT_ROD() - Bottom-up implementation");
}
public static int CUT_ROD2(int[] p, int n, String recursionStr){
System.err.println(recursionStr + "CUT_ROD2(p, "+n+")");
if(n == 0){
return 0;
}
int[] q = new int[n + 1];
int qMax = Integer.MIN_VALUE;
recursionStr += '\t';
for(int i = 1; i <= n; i++){
q[i] = p[i] + CUT_ROD2(p, n - i, recursionStr);
qMax = Math.max(qMax, q[i]);
}
System.err.print(recursionStr + " ");
for(int i = 1; i <= n; i++){
if(i < 10){
System.err.print(" ");
}
System.err.print(i + " ");
}
System.err.println("");
System.err.print(recursionStr + "q:");
for(int i = 1; i <= n; i++){
if(q[i] < 10){
System.err.print(" ");
}
System.err.print(q[i] + " ");
}
System.err.println("");
return qMax;
}
public static int MEMOIZED_CUT_ROD2(int[] p, int n){
int[] r = new int[n+1];
for(int i = 0; i <= n; i++){
r[i] = Integer.MIN_VALUE;
}
String recStr = "";
return MEMOIZED_CUT_ROD_AUX2(p, n, r, recStr);
}
public static int MEMOIZED_CUT_ROD_AUX2(int[] p, int n, int[] r, String recStr){
System.err.println(recStr + "MEMOIZED_CUT_ROD_AUX2(p, "+n+", r)");
if(r[n] >= 0){
System.err.println(recStr+"MEMOIZED_CUT_ROD_AUX2(p, "+n+", r) returning "+r[n]+" memoized");
return r[n];
}
int q;
if(n == 0){
q = 0;
}else{
recStr += '\t';
q = Integer.MIN_VALUE;
for(int i = 1; i <= n; i++){
q = Math.max(q, p[i] + MEMOIZED_CUT_ROD_AUX2(p, n - i, r, recStr));
System.err.println(recStr+"i: "+i+", q: "+q);
}
}
r[n] = q;
System.err.println(recStr+"MEMOIZED_CUT_ROD_AUX2(p, "+n+", r) returning "+q);
return q;
}
public static int BOTTOM_UP_CUT_ROD2(int[] p, int n){
System.err.println("BOTTOM_UP_CUT_ROD2(p, "+n+")");
int[] r = new int[n+1];
r[0] = 0;
for(int j = 1; j <= n; j++){
int q = Integer.MIN_VALUE;
System.err.println("j: "+j);
for(int i = 1; i <= j; i++){
if(q < p[i] + r[j - i]){
q = p[i] + r[j - i];
System.err.println("\ti: "+i+", q: "+q);
}
}
r[j] = q;
}
return r[n];
}
}