Title Link: http://acdream.info/problem?pid=1076
This question DP's state is very good design, dp[i][j] represents the command I when, the entire arrangement state is J, the entire arrangement altogether is 120, the preprocessing can be
So the problem is that for an instruction how to quickly get this entire interval of the permutation product, this step in fact, using a segment tree maintenance can be, but pay attention to the permutation is not satisfied with the Exchange law, so the positive sequence is to be saved again
Code:
#include <cstdio> #include <cstring> #include <algorithm>using namespace std;int N, M;int to[55555], Num[125][5];int a[5];void Init () {for (int i = 0; i < 5; i++) A[i] = i + 1; int cnt = 0; do {int sum = 0; for (int i = 0; i < 5; i++) {sum = sum * + a[i]; Num[cnt][i] = A[i]; } To[sum] = cnt++; } while (Next_permutation (A, A + 5));} const int N = 100005;struct Node {int L, r, S[2];} node[n * 4]; #define Lson (x) ((x<<1) +1) #define Rson (x) ((x< <1) +2) int Gao (int a, int b) {int sum = 0; for (int i = 0; i < 5; i++) {a[i] = Num[b][num[a][i]-1]; sum = sum * ten + a[i]; } return to[sum];} void pushup (int x) {Node[x].s[0] = Gao (Node[lson (x)].s[0], Node[rson (x)].s[0]); Node[x].s[1] = Gao (Node[rson (x)].s[1], Node[lson (x)].s[1]);} void build (int l, int r, int x = 0) {node[x].l = l; node[x].r = R; if (L = = r) {int sum = 0, tmp; for (int i = 0; I < 5; i++) {scanf ("%d", &tmp); sum = SUM * ten + tmp; } Node[x].s[0] = node[x].s[1] = To[sum]; Return } int mid = (L + r)/2; Build (L, Mid, Lson (x)); Build (mid + 1, R, Rson (x)); Pushup (x);} int get (int l, int r, int tp, int x = 0) {if (node[x].l >= l && node[x].r <= R) return NODE[X].S[TP]; int mid = (NODE[X].L + NODE[X].R)/2; if (l <= mid && R > Mid) {if (tp = = 0) return Gao (Get (L, R, TP, Lson (x)), Get (L, R, TP, Rson (x))); else return Gao (get (L, R, TP, Rson (x)), Get (L, R, TP, Lson (x))); } else if (L <= mid) return get (L, R, TP, Lson (x)); else if (R > Mid) return get (L, R, TP, Rson (x));} const int INF = 0x3f3f3f3f;int s[105], t[105], f[105];int dp[105][125];int main () {init (); while (~SCANF ("%d%d", &n, &m)) {build (1, N); for (int i = 0, I <= m; i++) for (int j = 0; J <; J + +) dp[i][j] = INF;for (int i = 1; I <= m; i++) {scanf ("%d%d", &s[i], &t[i]); F[i] = 0; if (S[i] > T[i]) {swap (s[i], t[i]); F[i] = 1; }} int sum = 0, tmp; for (int i = 0; i < 5; i++) {scanf ("%d", &tmp); sum = SUM * ten + tmp; } Dp[0][to[sum]] = 0; for (int i = 1; I <= m; i++) {int sb = GET (S[i], t[i], f[i]); for (int j = 0; J <; J + +) {if (dp[i-1][j] = = INF) continue; int NXT = Gao (j, SB); Dp[i][j] = min (Dp[i][j], dp[i-1][j]); DP[I][NXT] = min (dp[i][nxt], Dp[i-1][j] + max (S[i]-t[i], T[i]-s[i]) + 1); }} if (dp[m][to[12345] = = INF) printf (" -1\n"); else printf ("%d\n", dp[m][to[12345]]); } return 0;}
Acdream 1076 XXX Robot (DP + segment tree)