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