Question:
Give two equal-length numeric strings s1 and s2. Each operation can add up to three consecutive steps + 1 or-1. If 9 is exceeded, it is changed to 0. If it is less than 0, it is changed to 9. Ask the minimum number of steps from s1 to s2.
Solution:
Each digit can be moved correctly to a maximum of five digits. If one digit can be moved, the maximum value is 1000x5 = 5000.
BFS cannot be used directly because the length is 1000 too large.
Because each change affects up to three digits, the previous I-3 bit does not change, so you can set dp [I] [j] [k] to handle the I bit, and the last two are j, k, the front of the I-2 bit is the original string s1, to achieve the final s2 before I bit moving the smallest step number.
When transferring, first move the I-th digit correctly, and then enumerate the possible statuses of the first two digits when moving the I-th digit, at this time the number of steps to move the I-2 to be less than or equal to the I-1, The I-1 to be less than or equal to the I, then update the status of dp [I] based on the status of dp [I-1.
For example, if three digits need to move 2, 3, 4, and 3rd digits respectively, they need to move four digits. When moving 3rd digits, you can move both digits first, and then move the last two digits to one digit, the last one moves another one.
This type of dp does less, and more States will be analyzed in the future.
Code:
<SPAN style = "FONT-SIZE: 14px "> # include <iostream> # include <cmath> # include <cstdio> # include <cstdlib> # include <string> # include <cstring> # include <algorithm> # include <vector> # include <map> # include <set> # include <stack> # include <list> # include <queue> # define eps 1e-6 # define INF 0x1f1f1f1f # define PI acos (-1.0) # define ll _ int64 # define lson l, m, (rt <1) # define rson m + 1, r, (rt <1) | 1 // # pragma comment (linker, "/stacks: 1024 1000000,1024000000 ") using namespace std;/* freopen (" data. in "," r ", stdin); freopen (" data. out "," w ", stdout); */# define Maxn 1100 // up to 1000 * 5int dp [Maxn] [12] [12]; // dp [I] [x] [y] indicates that the current I bit is processed, and the last two digits are x and y, minimum number of steps required to go to the last I bit int a [Maxn], B [Maxn]; char sa [Maxn]; int main () {while (~ Scanf ("% s", sa) {int n = strlen (sa); for (int I = 1; I <= n; I ++) a [I] = sa [I-1]-'0'; scanf ("% s", sa); for (int I = 1; I <= n; I ++) B [I] = sa [I-1]-'0'; memset (dp, INF, sizeof (dp); dp [0] [0] [0] = 0; for (int I = 1; I <= n; I ++) {for (int x = 0; x <= 9; x ++) {if (I = 1 & x) // if there is only one bit, all data is processed as x = 0. continue; for (int y = 0; y <= 9; y ++) {int up = (B [I]-y + 10) % 10; // The Current BIT must meet the requirement int dow = (y-B [I] + 10) % 10; if (I = 1) // at this time, x must be 0 dp [I] [x] [y] = min (up, dow); else if (I = 2) {int xx = 0; // The I-2 position is 0, indicating that there is only one digit for (int j = 0; j <= up; j ++) // convert to {int yy = (x + j) % 10; // when the current bit meets the requirements, the first digit can move up dp [I] [x] [y] = min (dp [I] [x] [y], dp [I-1] [xx] [yy] + up);} for (int j = 0; j <= dow; j ++) // reverse {int yy = (x-j + 10) % 10; dp [I] [x] [y] = min (dp [I] [x] [y], dp [I-1] [xx] [yy] + dow );}} else // The I-bit up or dow state that can be reached by the I-1-bit and the I-2-bit {for (int j = 0; j <= up; j ++) // 2 3 4 first three move 2 then two move 1 last move 1 for (int p = j; p <= up; p ++) // must satisfy the I-1 bit moving greater than or equal to the I-2 bit, {int xx = (a [I-2] + j) % 10; int yy = (x + p) % 10; dp [I] [x] [y] = min (dp [I] [x] [y], dp [I-1] [xx] [yy] + up);} for (int j = 0; j <= dow; j ++) for (int p = j; p <= dow; p ++) {int xx = (a [I-2]-j) + 10) % 10; int yy = (x-p + 10) % 10; dp [I] [x] [y] = min (dp [I] [x] [y], dp [I-1] [xx] [yy] + dow) ;}}}if (n = 1) printf ("% d \ n ", dp [1] [0] [a [1]); else printf ("% d \ n ", dp [n] [a [n-1] [a [n]);} return 0 ;}</SPAN>