浅谈从搜索到动归
2019-06-09 23:26
871 查看
浅谈从搜索到动归
搜索
搜索的思路其实就是暴力破解(枚举每种可能的情况)
一般用dfs的相对较多,dfs是递归的代码结构,简洁明了,思路清晰
搜索的时候会形成一颗搜索树,整个搜索过程相当于在遍历这个搜索树
搜索树可通过剪枝来优化,可以理解为把这棵树上多余的枝叶剪去,更快的找到所需的答案
这里依然以01背包为例
题目概述:在n件物品取出若干件放在空间为c的背包里,每件物品的体积为w1 w2...wn,与之相对应的价值为v1 v2...vn,最终使背包所装物品的总价值最高
用普通的搜索来写,就是在选取每个物品的时候,有两种选择 拿or不拿
时间复杂度为O(2^n)
int w[105],v[105]; int n,c,res=0; void dfs(int idx,int c,int val){ if(c<0) return; if(idx==n){ res=max(res,val); return; } dfs(idx+1,c-w[idx],val+v[idx]); //拿这个物品 dfs(idx+1,c,val); //不拿这个物品 } int main(){ cin>>c>>n; for(int i=0;i<n;++i) cin>>w[i]>>v[i]; dfs(0,c,0); cout<<res; return 0; }
记忆化搜索
搜索过程中,往往包含着很多重复的计算
dfs递归参数中相同的idx和c,返回值一样,这样可以通过一个二维数组来记录
遇到相同的idx和c时,直接返回记忆化数组中之前算好的值即可
int w[105],v[105]; int mem[105][1005]; //记忆化数组 int n,c,res=0; int dfs(int idx,int c){ if(mem[idx][c]!=-1) return mem[idx][c]; //之前已经算好了,直接返回 if(idx==n) return mem[idx][c]=0; int t1=0,t2=0; if(c>=w[idx]) t1=dfs(idx+1,c-w[idx])+v[idx]; //拿这个物品 t2=dfs(idx+1,c); //不拿这个物品 return mem[idx][c]=max(t1,t2); } int main(){ cin>>c>>n; for(int i=0;i<n;++i) cin>>w[i]>>v[i]; memset(mem,-1,sizeof(mem)); cout<<dfs(0,c); return 0; }
动态规划
动态规划关键是在于:状态转移
从一个已求解的状态转移到一个新的状态
记忆化搜索是建立一个记忆化数组存储dfs递归函数不同参数的返回值
而动态规划也是建立一个状态转移数组存储已求解的状态
int dfs(int idx, int c) 中的参数idx和c 对应着 dp[i][j] 中的数组下标i和j
int n,c; int w[105],v[105]; int dp[105][1005]; //dp[i][j] 表示取到第i个物品时,背包容量为j int main(){ cin>>c>>n; for(int i=1;i<=n;++i) cin>>w[i]>>v[i]; for(int i=1;i<=n;++i) for(int j=1;j<=c;++j){ if(w[i]>j) dp[i][j]=dp[i-1][j]; else dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]); } cout<<dp [c]; return 0; }
相关文章推荐
- 浅谈种子搜索算法及C++实现方法
- 浅谈小型数据库增量搜索
- 搜索背后的奥秘——浅谈语义主题计算
- 搜索背后的奥秘——浅谈语义主题计算
- 浅谈中文文本自动纠错在影视剧搜索中应用与Java实现
- 搜索背后的奥秘——浅谈语义主题计算
- BZOJ 1673 浅谈深度优先式搜索及斐波拉契启发式AstaR剪枝
- mysql 的搜索处理 浅谈
- lucene实现搜索浅谈
- 浅谈部分搜索+高效算法在搜索问题中的应用 by 楼天城
- 【浅谈折半搜索】POJ1186[方程的解数]题解
- BZOJ 1085 浅谈迭代加深式法则及Astar启发式搜索路径诱导
- 搜索姿势浅谈
- 搜索背后的奥秘——浅谈语义主题计算
- 主要手段 - 浅谈搜索优化
- 浅谈Maven 项目中依赖的搜索顺序
- 搜索背后的奥秘——浅谈语义主题计算
- 浅谈淘宝类目属性体系:商品搜索背后的逻辑架构
- 搜索背后的奥秘——浅谈语义主题计算
- 搜索背后的奥秘——浅谈语义主题计算