早期西工大机试 背包和船装载

0-1背包问题

问题描述

给定一组有固定价值和固定重量的物品,以及一个已知最大承重量的背包,求在不超过背包最大承重量的前提下,能放进背包里面的物品的最大总价值。

思路

该问题的解决思路是动态规划,为减少递归的重复计算,定义一个二维数组B[N] [C]保存计算过的值,B[i] [j] 表示前i件物品放入容量为j的背包中所能获得的最大价值

如果只考虑第i件物品的放与不放,那么问题就转化为一个比较简单的形式:

(1) 当第i件物品太大,放不进去 ,则最大价值为前i-1件物品放入容量为j的背包,即B[i] [j] =B[i-1] [j] ,

(2)当第i件物品可以放入,不放入这件物品的价值是前i-1件物品放入容量为j的背包所能获得的最大价 值,放入这件物品的价值是前i-1件物品放入容量为当前背包容量减去这个物品重量的背包中的最 大价值加上这个物品的价值,取这两者的的最大价值:

​ 即B[i] [j]=max{B[i-1] [j], B[i-1] [j-weight[i]]+value[i]}

代码

#include <stdio.h>
#include <stdlib.h>
#define N 6
#define C 30
int value[N+1]={0,2,4,6,8,10,12};
int weight[N+1]={0,2,4,6,8,10,12};
int B[N+1][C+1];

void knapsack()
{
    int i,j;
    for(i=1;i<=N;i++){
        for(j=1;j<=C;j++){
            if(weight[i]>j)
                B[i][j]=B[i-1][j];
            else{
                int value1=B[i-1][j];
                int value2=B[i-1][j-weight[i]]+value[i];
                B[i][j]=value1>value2?value1:value2;
            }
        }
    }
}

int main()
{   
    knapsack();
    printf("%d\n",B[N][C]);
    return 0;
}

船装载问题

问题描述

有两艘船,载重量分别是c1、 c2,n个集装箱,重量是wi (i=1…n),且所有集装箱的总重量不超过c1+c2。确定是否有可能将所有集装箱全部装入两艘船。

思路

采用贪心的思想解决该问题,先尽可能的把第一艘船装满,然后看剩下的货物的能不能装进第二艘船

把货物装入第一艘船时采用递归的方式,不断回溯得到最大重量

只看第i个物品装不装

case 1:如果装不下第i件物品,就舍弃,考虑下面的货物是否装入

case 2:如果第i件物品可以装入,(1)更新最大重量,递归装入下面的物品,计算出装入i的最大重量 (2)不装入i,计算最大重量 (3)函数返回时比较(1)(2),取最大值

代码

#include <stdio.h>
#include <stdlib.h>
#define N 9
#define C1 50
#define C2 40
int w[N+1]={0,1,2,4,6,8,10,12,20,30};
int bestweight=0;
int weight=0;

int load(int x){
    if(x==N){

        if(weight>bestweight)
            weight=bestweight;
        return bestweight;
    }

    else{
            if(w[x]+weight<=C1){
            weight+=w[x];
            load(x+1);
            weight-=w[x];
        }
        load(x+1);

    }
}

int main(){
    int i,total=0;
    for(i=1;i<=9;i++)
        total+=w[i];
    load(1);
    if(C2>=total-bestweight)
        printf("Yes");
    else
        printf("No");
    return 0;
}

posted @ 2020-03-13 21:04  iClaire  阅读(244)  评论(0编辑  收藏  举报