Luo Gu P5507 [authorities] problem-solving report

topic

The basic ideas and algorithms (A *) bigwigs are talking about very detailed (not the point here ), here is a small but very practical optimization.

Only one step away from AC can take a look at

"Algorithm contest Step-up Guide" on page 124 writes "Valuation valuation function can not be greater than the actual value of the future", but in this problem, the slight increase that valuation can greatly improve operational efficiency program

Optimization ago

Optimized

All changes before and after the fast optimize efficiency nearly doubled, while optimizing the evaluation function is done with a high coefficient

General evaluation function: from the target state of each knob (1) and the sum of the difference divided by two (taken over the whole)

bool operator < (const e &a) const {
      return s + (v >> 1) + (v & 1) > a.s + (a.v >> 1) + (a.v & 1);
}

Note:

1, s refers to the number of the current state has been operated, v represents the difference from the target state of each knob and (evaluation function)

2, plus (v & 1) in order to take over the whole (with perhaps no)

3, the comparison function is written in the structure, the structure name e

Not difficult to find, the cost function is a really good ideal state (each operation so that the two knobs closer to the target state), but in reality difficult to achieve, you can make a more accurate valuation of some, and I in a high-v slightly larger than the coefficient of 1 (1.1, 1.2, 1.3) can (write the code below 1.3, because this is faster), you can own debugging

Becomes this:

bool operator < (const e &a) const {
      return s + (v >> 1) * 1.3 + (v & 1) > a.s + (a.v >> 1) * 1.3 + (a.v & 1);
}

Small changes would greatly improve the efficiency, fast almost 400ms (maximum of 300ms faster data points, not to 300ms Although the giant guy who always used )

The complete code

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
#define x now[a[p][now[p]]]
#define y now[p]
int tx, a[13][5], k[30000000], to[5] = {0, 2, 3, 4, 1};
struct e {
	int s, sum, v, now[13], step[20];
	bool operator < (const e &a) const {
      return s + (v >> 1) * 1.3 + (v & 1) > a.s + (a.v >> 1) * 1.3 + (a.v & 1);
    }
    inline void change (int p) {
		x = to[x], tx = x, y = to[y];
		v += (tx == 2) * 3 - (tx != 2) + (y == 2) * 3 - (y != 2);
    	step[++s] = p, sum += (tx == 1) - (tx == 2) + (y == 1) - (y == 2);
	}
	inline int get () {
		int tmp(0);
		for (int i = 1; i <= 12; ++i)  tmp = (tmp << 2) + now[i];
		return tmp;
	}
} top, tmp, t;
void Just_Do_It () {
	priority_queue <e> q;
	q.push (top);
	while (!q.empty()) {
		tmp = q.top();  q.pop();
		for (int i = 12; i; --i) {
			t = tmp;
			t.change (i);
			if (t.sum == 12) {
				printf ("%d\n", t.s);
				for (int i = 1; i <= t.s; ++i) printf ("%d ", t.step[i]);
				return;
			}
			int tt (t.get());
			if (k[tt]) continue;
			k[tt] = 1;
			q.push (t);
		}
	}
}
int main() {
	for (int i = 1; i <= 12; ++i) 
		scanf ("%d %d %d %d %d", &top.now[i], &a[i][1], &a[i][2], &a[i][3], &a[i][4]);
	for (int i = 1; i <= 12; ++i)  
	  top.sum += (top.now[i] == 1), top.v += (top.now[i] == 1) ? 0 : 5 - i;
	k[top.get()] = 1;
	Just_Do_It ();
	return 0;
} 

Guess you like

Origin www.cnblogs.com/whx666/p/11409447.html