【回溯】装载问题

 1 #include "stdio.h"
 2 #include "stdlib.h"
 3 int c1,c2,n;
 4 int w[1000],s[1000],bs[1000];
 5 int mw=0;
 6 void max(int c,int i,int cw)
 7 {
 8     if(i==n)
 9     {
10         if(cw>mw)
11         {
12             mw=cw;
13             int j;
14             for(j=0;j<n;j++)
15                 bs[j]=s[j];
16         }
17     }else{
18     if(c>=w[i]&&s[i]==0)
19     {
20         c-=w[i];
21         s[i]=1;
22         cw+=w[i];
23         max(c,i+1,cw);
24         c+=w[i];
25         s[i]=0;
26         cw-=w[i];
27     }
28     max(c,i+1,cw);
29     }
30 }
31 int main()
32 {
33     scanf("%d%d%d",&c1,&c2,&n);
34     while(c1!=0||c2!=0||n!=0)
35     {
36     int i;
37     bool flag=true;
38     for(i=0;i<n;i++)
39         scanf("%d",&w[i]);
40     for(i=0;i<n;i++)
41         s[i]=0;
42     for(i=0;i<n;i++)
43         bs[i]=0;
44     max(c1,0,0);
45     mw=0;
46     int l=0;
47     for(i=0;i<n;i++)
48     {
49         if(bs[i]==0)
50         {
51             l+=w[i];
52         }
53     }
54     if(l<=c2)
55         printf("Yes\n");
56     else
57         printf("No\n");
58     scanf("%d%d%d",&c1,&c2,&n);
59     }
60     return 0;
61 }

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

输入
多个测例,每个测例的输入占两行。第一行一次是c1、c2和n(n<=10);第二行n个整数表示wi (i=1…n)。n等于0标志输入结束。

输出
对于每个测例在单独的一行内输出Yes或No。

输入样例
7 8 2
8 7
7 9 2
8 8
0 0 0

输出样例
Yes
No

提示
求出不超过c1的最大值max,若总重量-max < c2则能装入到两艘船

时间: 2024-10-13 14:54:50

【回溯】装载问题的相关文章

回溯法求装载问题

1.回溯法 (1)描述:回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法.  (2)原理: 回溯法在问题的解空间树中,按深度优先策略,从根结点出发搜索解空间树.算法搜索至解空间树的任意一点时,先判断该结点是否包含问题的解.如果肯定不包含,则跳过对该结点为根的子树的搜索,逐层向其祖先结点回溯:否则,进入该子树,继续按深度优先策略搜索. 回溯法的基本做法是搜索,或是一种组织得井井有条的,

回溯法--无优化 最优装载问题

//#include "stdafx.h" // 回溯法,解空间分为排列数和子集树,前者是不同节点顺序的排列,后者是一个(0,1,...)的向量子集// 最大装载问题,是一个NP问题,目前只计算第一艘船,属于子集树// 有几个货物,子集树就有几层,当前题目为5层// 我感觉递归还是太过于精巧和经凑,很难挖空心思自己写出来,多熟悉别人现有的程序是一个好办法. #include<iostream>using namespace std; template<class T&

回溯法--装载问题

问题描述: 有一批共n个集装箱要装上2艘载重量分别为c1和c2的轮船,其中集装箱i的重量是wi,且不能超. 算法思想: 最优装载方案: 将第一艘轮船尽可能的装满: 然后将剩余的装载第二艘船上 算法描述: template <class Type> class Loading { friend Type MaxLoading(Type [],Type,int); private: void Backtrack(int i); int n; Type * w,c,cw,bestw; }; temp

回溯法——装载问题

问题描述: 有一批共n个集装箱要装上2艘载重量分别为c1和c2的轮船,其中集装箱i的重量是wi,且不能超,即Σwi<=c1+c2. 算法思想: --在给定的装载问题有解的情况下 最优装载方案: 首先将第一艘轮船尽可能的装满:  然后将剩余的集装箱装上第二艘轮船. 将第一艘轮船尽可能的装满等价于选取全体集装箱的一个子集,使该子集中集装箱重量之和最接近c1. 算法设计: 先考虑装载一艘轮船的情况,依次讨论每个集装箱的装载情况,共分为两种,要么装(1),要么不装(0),因此很明显其解空间树可以用子集树

回溯算法 - 最优装载

(1)问题描述:有一批共 n 个集装箱要装上 2 艘载重量分别为 capacity1 和 capacity2 的轮船,其中集装箱 i 的重量为 wi,且装载问题要求确定是否有一个合理的装载方案可将这些集装箱装上这 2 艘轮船.如果有,找出一种装载方案. 例如:当 n = 3, capacity1 = capacity2= 50, 且 w = [10, 40, 40] 时,则可以将集装箱 1 和 2 装到第一艘轮船上,而将集装箱 3 装到第二艘轮船上:如果 w = [20, 40, 40],则无法

noj算法 装载问题 回溯法

描述: 有两艘船,载重量分别是c1. c2,n个集装箱,重量是wi (i=1-n),且所有集装箱的总重量不超过c1+c2.确定是否有可能将所有集装箱全部装入两艘船. 输入: 多个测例,每个测例的输入占两行.第一行一次是c1.c2和n(n<=10):第二行n个整数表示wi (i=1-n).n等于0标志输入结束. 输出: 对于每个测例在单独的一行内输出Yes或No. 输入样例: 7 8 28 77 9 28 80 0 0 输出样例: YesNo 题解: 变形的01背包问题,先按最优解把c1装好,在看

回溯法 -数据结构与算法

1.回溯法算法思想: 定义: 回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”. 1.回溯法适用:有许多问题,当需要找出它的解集(全部解)或者要求回答什么解是满足某些约束条件的最优解时,往往要使用回溯法. 2.有组织的穷举式搜索:回溯法的基本做法是搜索或者有的组织穷尽搜索.它能避免搜索所有的可能性.即避免不必要的搜索.这种方

0-1背包-回溯法

算法描述: 0-1背包的回溯法,与装载问题的回溯法十分相似.在搜索解空间树时,只要其左儿子结点是一个可行结点,搜索就进入其左子树.当右子树中有可能包含最优解时才进入右子树进行搜索.否则将右子树剪去. 计算右子树上界的更好算法是: 将剩余物品依其单位重量价值排序,然后依次装入物品,直至装不下时,再装入该物品的一部分而装满背包. 算法实现: 由Bound函数计算当前节点处的上界. 类Knap的数据成员记录解空间树的节点信息,以减少参数传递及递归调用所需的栈空间. 在解空间树的当前扩展结点处,仅当要进

回溯法-01背包问题之一:递归模式

一.回溯法 回溯法是一个既带有系统性又带有跳跃性的搜索算法.它在包含问题的所有解的解空间树中按照深度优先的策略,从根节点出发搜索解空间树.算法搜索至解空间树的任一节点时,总是先判断该节点是否肯定不包含问题的解.如果肯定不包含,则跳过对以该节点为根的子树的系统搜索,逐层向其原先节点回溯.否则,进入该子树,继续按深度优先的策略进行搜索. 运用回溯法解题通常包含以下三个步骤: · 针对所给问题,定义问题的解空间: · 确定易于搜索的解空间结构: · 以深度优先的方式搜索解空间,并且在搜索过程中用剪枝函