装载问题

#include "cstdio"
#include "queue"
#define MAX 20   
#define INF 999
using namespace std;    

int n;  //集装箱数量
int w[MAX];  //集装箱的重量
int bestx[MAX];  //是否被装入第一艘船
int c;  //第一艘船的容量
int r[MAX];  //剩余载重

struct bnode
{
    struct bnode *parent;  //父结点
    int left;  //左孩子标志
};

struct heapNode
{
    struct bnode *b;  //指向活结点在子集树中的指针
    int level;  //结点在子集树中所在的层

    //从根结点到当前结点的路径所相应的载重量加上剩余集装箱重量之和
    int uweight;  //活结点优先级(上界),

    bool operator < (const heapNode &hn) const
    {
        return uweight < hn.uweight;
    }
};

//从根结点到当前结点的路径所相应的载重量加上剩余集装箱重量之和大的先出队列
priority_queue<heapNode> pq; 

void enHeap(int uw, bnode *parent, int isLeft, int i)  //入队列
{
    bnode *b = (bnode *)malloc(sizeof(bnode));
    b->parent = parent; 
    b->left = isLeft;
    heapNode hn;
    hn.level = i;
    hn.uweight = uw;
    hn.b = b;
    pq.push(hn);
}

void init(int n1, int c1, int weight[])
{
    n = n1;
    c = c1;
    int i;
    for(i=1; i<=n; i++)
        w[i] = weight[i];
    r[n] = 0;   //装入最后一个物品后,剩余载重为0
    for(i=n-1; i>0; i--)  
        r[i] = w[i+1] + r[i+1];
}

int maxLoading()
{ 
    bnode *e = NULL; //当前扩展结点
    heapNode hn;
    int i = 1;  //当前结点所在层
    int ew = 0;  //当前载重
    while(i!=n+1)  //还没有到叶结点时
    {
        if(ew+w[i]<=c)  //如果船还装得下当前的集装箱
            enHeap(ew+w[i]+r[i], e, 1, i+1);  //左子树
        enHeap(ew+r[i], e, 0, i+1);  //右子树

        hn = pq.top();  //取下一个扩展结点
        pq.pop();
        ew = hn.uweight - r[i];  //总载重-剩余载重=当前载重
        e = hn.b;   
        i = hn.level;
    }

    for(i=n; i>0; i--)  //从叶子结点到根节点构造最优解
    {
        bestx[i] = e->left;
        e = e->parent;
    }
    return ew;
}

int main()
{
    int n1 = 4;
    int c1 = 70;
    int weight[] = {0, 20, 10, 26, 15};
    init(n1, c1, weight);
    printf("船载重为:%d\n", c1);
    int sum = maxLoading();
    printf("集装箱重量为:\n");
    int i;
    for(i=1; i<=n; i++)
        printf("%d ", w[i]);
    printf("\n最优载重为:%d\n", sum);
    return 0;
}

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值