贪心法(部分背包问题)

1、部分背包问题

#include<stdio.h> 

#define N 5 // 物品数量 
#define W 100 // 背包容量

int v_temp[N + 1], w_temp[N + 1]; // 物品价值数组 和 物品重量数组的临时数组
double vw_temp[N + 1]; // 物品单位重量价值数组的临时数组 

double answer[N + 1]; // 解方案数组 

// 归并排序 
// 归并排序
void merge_sort(int v[], int w[], double vw[], int l, int r) {
    if (l >= r) return;

    int mid = l + r >> 1;
    merge_sort(v, w, vw, l, mid), merge_sort(v, w, vw, mid + 1, r);

    int i = l, j = mid + 1, k = 1;
    while (i <= mid && j <= r)
    {
        if (vw[i] >= vw[j]) { // 按照 物品单位重量价值数组 从大到小的顺序排序
            vw_temp[k] = vw[i];
            v_temp[k] = v[i];
            w_temp[k] = w[i];

            k ++ , i ++ ;
        } else {
            vw_temp[k] = vw[j];
            v_temp[k] = v[j];
            w_temp[k] = w[j];

            k ++ , j ++ ;
        }
    }

    while (i <= mid) {
        vw_temp[k] = vw[i];
        v_temp[k] = v[i];
        w_temp[k] = w[i];

        k ++ , i ++ ;
    }

    while (j <= r) {
        vw_temp[k] = vw[j];
        v_temp[k] = v[j];
        w_temp[k] = w[j];
        k ++ , j ++ ;
    }

    for (i = l, j = 1; i <= r; i ++ , j ++ ) {
        vw[i] = vw_temp[j];
        v[i] = v_temp[j];
        w[i] = w_temp[j];
    }
}


// 显示物品价值、重量、单位重量数组 
void show(int v[], int w[], double vw[]) {
    int i;
    
    printf("物品价值数组:");
    for (i = 1; i <= N; i++)  printf("%d ", v[i]); 
    printf("\n");
    
    printf("物品重量数组:");
    for (i = 1; i <= N; i++)  printf("%d ", w[i]); 
    printf("\n");
    
    printf("物品单位重量数组:");
    for (i = 1; i <= N; i++)  printf("%.1lf ", vw[i]); 
    printf("\n");
}

double Max_Value(int v[], int w[], double vw[]) {
    double result = 0.0;
    
    int i;
    int W_temp = W;
    for (i = 1; i <= N; i++) {
        if(W_temp >= w[i]) { // 当前背包容量 大于等于 物品重量 就直接全部装入到背包中 
            answer[i] = 1.0;
            result = result + v[i];
            
            W_temp = W_temp - w[i];
        } else { // 当前背包容量 大于小于 物品重量 就应该将该物品的一部分装入到背包中 
            break;
        }
    }
    
    if (W_temp > 0 && i <=N) { // 当前背包有剩余容量 并且 还有可选物品 
        answer[i] = (double) W_temp / w[i];
    
        result = result + W_temp * vw[i];
        // result = result + (double) W_temp / w[i] * v[i];
    }
    
    return result;
    
} 

int main() {
    int v[] = {0, 60, 65, 40, 30, 20}; // 物品价值数组
    int w[] = {0, 50, 30, 40, 20, 10}; // 物品重量数组 
    
    double vw[N + 1]; // 物品单位重量价值数组
    
    int i;
    // 初始化 物品单位重量价值数组 
    for (i = 1; i <= N; i++) vw[i] = (double) v[i] / w[i]; 
    
    printf("排序前:\n");
    show(v, w, vw);    
        
    merge_sort(v, w, vw, 1, N);
    
    printf("排序后:\n");
    show(v, w, vw);    
    

    
    double result = Max_Value(v, w, vw);
    printf("\nresult = %.1lf\n", result);
    printf("\n");
    
    printf("解决方案结果:");
    for (i = 1; i <= N; i++) printf("%.1lf", answer[i]);
    
    return 0;
} 

2、时间复杂度

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值