切割钢管问题
最原始的代码:
#include<stdio.h> int mymax(int x,int y){ if(y>=x){ return y; } else { return x; } } int CUT(int *p,int n){ if( n==0 ){ return 0 ; } int q = 0; for(int i = 1 ; i <= n ; i++){ q = mymax(q,p[i]+CUT(p,n-i)) ; } return q; } int main(){ int p[5]={ 0,1,5,8,9 }; int n = 4 ; int q = CUT(p,n); printf("%d",q); return 0 ; }
自带备忘录的:
int memoized_cut_rod_aux(int* p, int n, int* r) { if (r[n] >= 0) { return r[n]; } int q = -1; if (n == 0) { q = 0; } else { for (int i = 1; i <= n; i++) { q = max(q, p[i] + memoized_cut_rod_aux(p, n - i, r)); } } r[n] = q; return q; } /* * 自顶向上的cut-rod的过程 */ int memoized_cut_rod(int* p, int n) { int* r = new int[n + 1]; //初始化r数组,r数组用来存放,某种解决方案的最大收益值,对于n长的钢条而言,有n+1种切割方案,所以数组n+1长 for (int i = 0; i <= n; i++) { r[i] = -1; } return memoized_cut_rod_aux(p, n, r); }
从底到上的:
/* * 自底向上的方式,先计算更小的子问题,然后再算较大的子问题,由于较大的子问题依赖于更小的子问题的答案,所以在计算较 * 大的子问题的时候,就无需再去计算更小的子问题,因为那答案已经计算好,且存储起来了 */ int bottom_up_cut_rod(int p[], int n) { int* r = new int[n + 1]; r[0] = 0; //将r[0]初始化为0,是因为0长的钢条没有收益 for (int j = 1; j <= n; j++) { int q = -1; /* * 这里不用i=0开始,因为i=0开始不合适,因为这里总长就是为j,而划分是i和j-i的划分,如果i等于0,那么 * 就意味着要知道r[j-0]=r[j]的值也就是j长的最好划分的收益,但是我们这里不知道。而且对于p[0]而言本身就没有意义 * p数组中有意义的数据下标是从1到n的 */ for (int i = 1; i <= j; i++) { q = max(q, p[i] + r[j - i]); // } r[j] = q; } return r[n]; }
完整代码: