AcWing 180. row of books

AStar worst case \ (O (log_2560 ^ 4) \)

With \ (AStar \) algorithm to do this problem, run the program \ (408ms \) .
Compared to \ (IDA * \) is \ (100ms \) is about to be a lot slower.
And \ (A * \) because it is \ (BFS \) , the code length is longer.

Reasons for the slow running should be two things:

  • With the three \ (STL \) ,STL junk ruined my youth
  • This question index soaring, is \ (560 \) , so \ (log \) instead of superimposing several times larger than the previous.

Evaluation function used is the same, namely:

\ (H (n) = \ lceil \ frac {adjacent positions on the wrong number} {3} \ rceil \)

Evaluation function explained in detailed proof & general explanations the y- .


Summed up what should choose when \ (A * \) or \ (IDA * \) :

  • When the dictionary requires a minimum order, said a lot of the state, when the index grew rapidly, use \ (IDA * \)
  • If the state easily said when exponential growth is slower, use \ (A * \) (note need not be used when the minimum lexicographical \ (A * \) , because he is not in accordance with the search order).

C ++ code

#include <cstdio>
#include <iostream>
#include <unordered_set>
#include <queue>
using namespace std;
typedef unsigned long long ULL;
const int N = 15, B = 17;
int n;
struct State{
    //v表示当前的状态,step表示步数,f表示当前估计值(答案)
    int v[N], step, f;
    //重载小于号
    bool operator < (const State &x) const{
        return f > x.f;
    }
}Start;
//检测是否到了目标状态
bool check(State x){
    for(int i = 0; i < n; i++)
        if(x.v[i] != i + 1) return false;
    return true;
}
//用于检测一个状态是否已经访问过了
unordered_set<ULL> s;
priority_queue<State> q;

//hash
ULL get(State x){
    ULL res = 0;
    for(int i = 0; i < n; i++)
        res = res * B + x.v[i];
    return res;
}
int f(State x){
    int res = 0;
    for(int i = 1; i < n; i++)
        if(x.v[i] - 1 != x.v[i - 1]) res++;
    return res % 3 ? res / 3 + 1 : res / 3;
}
int bfs(){
    while(q.size()) q.pop();
    Start.step = 0; Start.f = f(Start);
    q.push(Start); s.insert(get(Start));
    while(!q.empty()){
        State u = q.top(); q.pop();
        if(u.f >= 5) return 5;
        if(check(u)) return u.step;
        for(int l = 1; l < n; l++){
            for(int i = 0; i + l - 1 < n; i++){
                int j = i + l - 1;
                for(int k = i + l; k < n; k++){
                    State v; 
                    for(int f = 0; f < n; f++) v.v[f] = u.v[f];
                    for(int f = j + 1, t = i; f <= k; f++, t++)
                        v.v[t] = u.v[f];
                    for(int f = i, t = i + k - j; f <= j; f++, t++)
                        v.v[t] = u.v[f];
                    if(s.count(get(v)) > 0) continue; 
                    s.insert(get(v));
                    v.step = u.step + 1;
                    v.f = v.step + f(v);
                    q.push(v);
                }
            }
        }
    }
    return 5;
}

int main(){
    int T; scanf("%d", &T);
    while(T--){
        s.clear();
        scanf("%d", &n);
        for(int i = 0; i < n; i++)
            scanf("%d", &Start.v[i]);
        int res = bfs();
        if(res >= 5) puts("5 or more");
        else printf("%d\n", res);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/dmoransky/p/11404823.html
Row