educoder算法设计与分析 实验六 分支界限法

第1关:0-1背包

题目描述:
 
在这里插入图片描述

任务要求

输出一个数,代表能装入的最大价值

测试输入:

4 7
3 5 2 1
9 10 7 4

预期输出:

20

分析:

代码实现:

#include <iostream>
#include <algorithm> //sort函数包含的头文件
using namespace std;
typedef struct p
{
    struct p *pr;
    int wt;
    int vt;
    int ch; //标志
    int lev;

} EM;

typedef struct
{
    EM *em[1000];
    int start;
    int tail;
} queue;

bool cmp(EM *a, EM *b)
{
    return a->vt > b->vt;
}

void add(queue *q, EM *em)
{
    q->em[q->tail] = em;
    q->tail++;
    if (q->tail - q->start > 1)
    {
        sort(q->em + (q->start), (q->em) + (q->tail), cmp);
    }
    return;
}

EM *del(queue *q)
{
    q->start++;
    return q->em[q->start - 1];
}

void Add_Q(queue *Q, EM *em, int wt, int vt, int i, int n, int ch)
{

    EM *newE = (EM *)malloc(sizeof(EM));
    newE->pr = em;
    newE->vt = vt;
    newE->wt = wt;
    newE->ch = ch;
    newE->lev = i;
    add(Q, newE);
}

int BestValue(int c, int n, int w[], int v[])
{
    queue *Q = (queue *)malloc(sizeof(queue));
    Q->start = Q->tail = 0;
    EM *Em = (EM *)malloc(sizeof(EM));
    Em->pr = NULL;
    Em->lev = 0;
    Em->vt = 0;
    Em->wt = 0;
    while (Em->lev <= n)
    {

        if (Em->wt + w[Em->lev + 1] <= c)
        {
            Add_Q(Q, Em, Em->wt + w[Em->lev + 1], Em->vt + v[Em->lev + 1], Em->lev + 1, n, 1);
        }
        Add_Q(Q, Em, Em->wt, Em->vt, Em->lev + 1, n, 1);
        Em = del(Q);
    }
    return Em->vt;
}

int main()
{
    int n, c;
    cin>>n>>c;
    int w[n + 1], v[n + 1];
    for (int i = 1; i <= n; i++)
    {

        cin >> w[i];
    }
    for (int i = 1; i <= n; i++)
    {

        cin >> v[i];
    }

    cout << BestValue(c, n, w, v) << endl;

    return 0;
}

第2关:装载问题 (最优队列法)

题目描述:
在这里插入图片描述

输入格式
第一行输入n,代表有n个城市。
接下来n行每行输入n个数,第i行j列的值代表i市到j市的距离,0代表城市之间不通
注意:起点和终点都为1
n<7,城市之间的距离都不超过100

输出格式
第一行输出最少的旅行费用

Sample Input

4
0 30 6 4
30 0 5 10
6 5 0 20
4 10 20 0

Sample Output

25
分析:

代码实现:

#include <iostream>
#include <algorithm> //sort函数包含的头文件
using namespace std;
typedef struct data_EM
{
    struct data_EM *pr;
    int vt;
    int lev;
    int *city; //记录当前已经去过的城市
} EM;

typedef struct data_Q
{
    EM *em[100];
    int start;
    int tail;

} Q;
bool cmp(EM *a, EM *b)
{
    return a->vt < b->vt;
}

void add_e(Q *q, EM *em)
{
    q->em[q->tail] = em;
    q->tail++;
    if (q->tail - q->start > 1)
    {
        sort(q->em + (q->start), (q->em) + (q->tail), cmp);
    }
    return;
}

EM *del_e(Q *q)
{
    q->start++;
    return q->em[q->start - 1];
}

void add_Q(Q *q, EM *em, int vt, int i, int city)
{
    EM *newEm = (EM *)malloc(sizeof(EM));
    newEm->pr = em;
    newEm->lev = i;
    newEm->vt = vt;
    newEm->city = (int *)malloc(sizeof(int) * i);
    newEm->city[i - 1] = city;
    for (int j = 0; j < i - 1; j++)
    {
        newEm->city[j] = em->city[j];
    }
    add_e(q, newEm);
    return;
}

int BestTsp(int **T, int n)
{
    Q *q = (Q *)malloc(sizeof(Q));
    EM *Em = (EM *)malloc(sizeof(EM));
    q->start=q->tail=0;
    Em->pr = NULL;
    Em->vt = 0;
    Em->city = (int *)malloc(sizeof(int));
    Em->city[0] = 1;
    Em->lev = 1;
    while (Em->lev <= n)
    {
        for (int j = 2; j <= n; j++)
        {
            bool ctiy_k = true;
            for (int k = 0; k < Em->lev; k++)
            {
                if (j == Em->city[k])
                {
                    ctiy_k = false;
                }
            }
            if (ctiy_k)
            {
                add_Q(q, Em, T[Em->city[Em->lev - 1]][j] + Em->vt + (Em->lev + 1 == n ? T[j][1] : 0), Em->lev + 1, j);
            }
        }
        Em = del_e(q);
        if (Em->lev == n || q->start == q->tail)
        {
            break;
        }
    }
    return Em->vt;
}

int main()
{
    int n;
    cin >> n;
    int **T = (int **)malloc(sizeof(int *) * (n + 1));
    for (int i = 1; i <= n; i++)
    {
        T[i] = (int *)malloc(sizeof(int));
    }
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {

            cin >> T[i][j];
        }
    }

    cout << BestTsp(T, n) << endl;
    return 0;
}

注:答案不唯一,仅供参考。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xingcheng--dp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值