算法第五章作业

1. 请用回溯法的方法分析“最小重量机器设计问题”

本题给出了n个零部件,m个供应商,每个供应商给的零件的重量和价格。要求总价格不超过d的最小重量机器设计。

限制条件:总价格<=d.

剪枝条件:当前的重量要<=当前保存的最小重量,否则return

如代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define pb push_back
 4 const int N=35;
 5 int n,m,d;//n部件 m供应商 d最小重量机器设计 
 6 //求价格不超过d的最小重量 
 7 struct node
 8 {
 9     int w,v;
10 }a[N][N];
11 int ans=0x3f3f3f3f;
12 vector<int>anss,temp;
13 void dfs(int u,int val,int weight)//参数分别表示:某一层,总共价值,总共重量
14 {
15     if(u>n)//跑完最后一层
16     {
17         if(ans>weight&&val<=d)//满足更新最小重量的条件就更新
18         {
19             ans=weight;
20             anss=temp;//更新答案
21         }
22         return;
23     }
24     else
25     {
26         for(int i=1;i<=m;i++)//循环遍历该层的不同供应商给的每一个零件
27         {
28             if(val+a[u][i].v<=d&&weight+a[u][i].w<ans)//满足条件就开始往下搜索
29             {
30                 temp.pb(i);
31                 dfs(u+1,val+a[u][i].v,weight+a[u][i].w);//下一层就u+1,价值和重量都要更新
32                 temp.pop_back();//回溯要恢复现场
33             }
34         }
35     }
36 } 
37 int main()
38 {
39     cin>>n>>m>>d;
40     for(int i=1;i<=n;i++)
41         for(int j=1;j<=m;j++)
42         {
43             cin>>a[i][j].v;
44         }
45     for(int i=1;i<=n;i++)
46         for(int j=1;j<=m;j++)
47         {
48             cin>>a[i][j].w;
49         }
50     dfs(1,0,0);//从第一层,价值为0,重量为0开始搜索
51     cout<<ans<<endl;
52     for(auto x:anss) cout<<x<<" ";
53     return 0;
54 }

 

1.1 说明“最小重量机器设计问题"的解空间

解空间是它的所有可能的解构成的集合。

因此此问题的解空间是价格不超过d的所有可行总重量和供应商的集合。

按照样例解空间为:{{1,3,1},{1,3,2},{1,3,3}}

1.2 说明 “最小重量机器设计问题"的解空间树

解空间树是价格不超过d的所有可行总重量和供应商的树。

1.3 在遍历解空间树的过程中,每个结点的状态值是什么

 struct node
 {
     int w,v;
 }a[N][N];

当前的总价格和总重量。

2. 你对回溯算法的理解

我对回溯算法的理解是一种深度优先搜索策略的枚举。解空间树是对此问题的每种答案的枚举的集合。通过深度优先搜索的策略,每搜到一个结点,判断此节点是否符合条件(题目条件或剪枝条件),符合再继续往下搜,如果一直符合就搜到底,若不符合就返回上一步。
回溯法是对隐式图的深度优先搜索,找解其实就是找符合条件的路径。

posted @ 2021-12-10 20:51  karshey  阅读(38)  评论(0编辑  收藏  举报