PTA 6-1 求解复杂装载问题(回溯法)

有一批共n个集装箱要装上两艘载重量分别为c1和c2的轮船,其中集装箱i的重量为wi,且w1+w2+…+wn≤c1+c2。 装载问题要求确定是否有一个合理的装载方案可将这些集装箱装上这两艘轮船。如果有,找出一种装载方案。

函数接口定义:

void dfs(int tw,int rw,int op[],int i);
bool solve();

其中tw表示选择的集装箱重量和,rw表示剩余集装箱的重量和,op表示一个解,即一个选择方案,i表示考虑的集装箱i

裁判测试程序样例:

#include <stdio.h>
#include <string.h>
#define MAXN 20                        //最多集装箱个数
#include <iostream>
using namespace std;
//问题表示
int w[MAXN]={0};                //各集装箱重量,不用下标0的元素
int    n;
int c1,c2;
int maxw=0;                            //存放第一艘轮船最优解的总重量
int x[MAXN];                        //存放第一艘轮船最优解向量

void dispasolution(int n)        //输出一个解
{
    for (int j=1;j<=n;j++)
        if (x[j]==1)
            printf("%d ",j);
    cout<<endl; 
    for (int j=1;j<=n;j++)
        if (x[j]==0)
            printf("%d ",j);    

}
void dfs(int tw,int rw,int op[],int i);
bool solve();

int main()
{
    cin>>n;
    for(int i=1;i<=n;i++) 
      cin>>w[i];
    cin>>c1>>c2;
    int op[MAXN];                //存放临时解
    memset(op,0,sizeof(op));
    int rw=0;
    for (int i=1;i<=n;i++)
        rw+=w[i];
    dfs(0,rw,op,1);                //求第一艘轮船的最优解

    if (solve())                //输出结果
    {
        dispasolution(n);
    }
    else
        printf("No solution");
    return 0;
}

/* 请在这里填写答案 */

输入格式:

第一行输入集装箱个数n,第二行依次输入n个集装箱的重量wi,第三行输入两艘载重量c1和c2。

输出格式:

第一行输出第一艘选取的集装箱编号,第二行输出第二艘选取的集装箱编号。(编号按输入顺序从1开始)
若没有合理的装载方案,输出“No solution”。

输入样例1:

3
10 40 40
50 50
 

输出样例1:

1 2 
3   
 

解题方法:

由于集装箱放在第一或第二条船上。所以该问题可以采用二叉树的存储结构。以数组的形式将集装箱存储的位置结果保存(这里用op[i]为0或1来表示存储的第一或者第二条船)。

我们采用的算法是回溯法,先尽可能把集装箱装在第一条船上(等同于在二差树里面把op[i]==0),每次先判断当前的tw表示选择的集装箱重量和是不是大于第一个集装箱的容纳量。如果大于就把下一个集装箱放在第二个集装箱。然后通过不断递归可以达到深度扩展的功能。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值