poj-3134 ida*||记录路径bfs

http://poj.org/problem?id=3134

题意是一个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[n]<<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;
    }
}



 

posted @ 2016-04-30 20:07  zhangxianlong  阅读(84)  评论(0编辑  收藏  举报