动态规划

切割钢管问题

最原始的代码:

#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];  
}  

完整代码:

原文地址:https://www.cnblogs.com/da-peng/p/5687603.html