poj-3134 ida*||记录路径bfs
2016-04-30 20:07
471 查看
http://poj.org/problem?id=3134
题意是一个x的n次方,最快的运算个方式。。。不会做看题解是个IDDFS。。。太高深暂时先不研究,以后填坑。。
(回来填坑)
这里考虑一个BFS的做法,一开始以为直接记录父节点类似并查集那样的寻找相关然后记录最小值就可以了。。后来发现相等的时候父节点不一定取哪个最好,
这里学习了一个方法,在节点里面记录来的路径,由于自己不会算空间复杂度,还以为会爆炸,这里学习一下。。这样如果ans相等就也入队列就好了
然后就搜索就可以了,常数稍微好一点就水过了。。据说可以限制向上求的步数来加快。。暂时还不太理解。。
代码如下,暴力BFS水过。。。
(ida* 思路很好理解,关键就是设计估价函数了,当然要注意这个“距离”估价不能“长于”最优“路径”否则得不到最优解,事实上我们这个题就指数增长来估价就可以了,代码非常好写,实际上很多路径有关的bfs都可以写成iddif或者ida*,毕竟利用dfs路径什么的在栈上操作太方便了。。)
PS 以前写的不忍直视啊。。。
ida*代码:
#include<iostream>
using namespace std;
const int maxn=1e6+10;
using namespace std;
int n,ans,id,tmp[maxn];
int ida(int x,int cnt){
if(x<=0||cnt>ans||(x<<(ans-cnt))<n) return 0;
if(x==n) return 1;
tmp[id++]=x;
for(int i=0;i<id;i++)
if(ida(x+tmp[i],cnt+1)||ida(x-tmp[i],cnt+1)) return 1;
--id;
return 0;
}
int main(){
while(cin>>n,n){
ans=id=0;
while(!ida(1,0)) ans++;
cout<<ans<<endl;
}
}
题意是一个x的n次方,最快的运算个方式。。。不会做看题解是个IDDFS。。。太高深暂时先不研究,以后填坑。。
(回来填坑)
这里考虑一个BFS的做法,一开始以为直接记录父节点类似并查集那样的寻找相关然后记录最小值就可以了。。后来发现相等的时候父节点不一定取哪个最好,
这里学习了一个方法,在节点里面记录来的路径,由于自己不会算空间复杂度,还以为会爆炸,这里学习一下。。这样如果ans相等就也入队列就好了
然后就搜索就可以了,常数稍微好一点就水过了。。据说可以限制向上求的步数来加快。。暂时还不太理解。。
代码如下,暴力BFS水过。。。
(ida* 思路很好理解,关键就是设计估价函数了,当然要注意这个“距离”估价不能“长于”最优“路径”否则得不到最优解,事实上我们这个题就指数增长来估价就可以了,代码非常好写,实际上很多路径有关的bfs都可以写成iddif或者ida*,毕竟利用dfs路径什么的在栈上操作太方便了。。)
PS 以前写的不忍直视啊。。。
#include <iostream> #include <cmath> #include <cstring> #include <map> #include <set> #include <cstdio> #include <deque> #include <vector> #include <queue> #include <algorithm> using namespace std; int ans[1101]; struct node{ vector<int> s; int x; int val; node(){}; node(int xx,int vv,vector<int> ss):x(xx),val(vv),s(ss){}; }; void bfs(){ queue<node> Q; vector<int> v; v.push_back(1); Q.push(node(1,0,v)); ans[1]=0; node ad; node x; while(!Q.empty()){ x=Q.front(); Q.pop(); if(x.val!=ans[x.x]) continue; for(int i=0;i<x.s.size();i++){ if(x.x+x.s[i]>=1005) continue; if(ans[x.x+x.s[i]]>=x.val+1){ ans[x.x+x.s[i]]=x.val+1; ad=x; ad.val=x.val+1; ad.x=x.x+x.s[i]; ad.s.push_back(x.x+x.s[i]); Q.push(ad); } } for(int i=0;i<x.s.size();i++){ if(x.x-x.s[i]<1) continue; if(ans[x.x-x.s[i]]>=x.val+1){ ans[x.x-x.s[i]]=x.val+1; ad=x; ad.val=x.val+1; ad.x=x.x-x.s[i]; ad.s.push_back(x.x-x.s[i]); Q.push(ad); } } } } int main() { int n; memset(ans,0x3f3f3f3f,sizeof(ans)); bfs(); while(cin>>n){ if(n==0) break; cout<<ans <<endl; } return 0; }
ida*代码:
#include<iostream>
using namespace std;
const int maxn=1e6+10;
using namespace std;
int n,ans,id,tmp[maxn];
int ida(int x,int cnt){
if(x<=0||cnt>ans||(x<<(ans-cnt))<n) return 0;
if(x==n) return 1;
tmp[id++]=x;
for(int i=0;i<id;i++)
if(ida(x+tmp[i],cnt+1)||ida(x-tmp[i],cnt+1)) return 1;
--id;
return 0;
}
int main(){
while(cin>>n,n){
ans=id=0;
while(!ida(1,0)) ans++;
cout<<ans<<endl;
}
}
相关文章推荐
- SQL Server 2008 评估期已过解决方法
- HDU 1166 线段树模板&树状数组模板
- HDU 1166 线段树模板&树状数组模板
- 加大VirtualBox Image大小的办法
- 【刷题笔记/剑指Offer】51-61
- 第九周学习进度条
- 构建自己的PHP框架--构建缓存组件(2)
- 动态规划常见问题所涉及的公式(转载)
- C经典 写函数进行数据交换
- windows安装Linux系列双系统时基本的注意事项
- maven学习系列4----依赖
- 敏捷管理视频
- Linux内核期末总结
- day3.23总结_Set和Map
- Java核心知识点-JVM再深入
- 构建之法阅读笔记06
- 移动前端第二弹:善用meta
- 判断用户是否登录
- 机器学习笔记05:正则化(Regularization)、过拟合(Overfitting)
- JAVA监听器原理