uva1631-Locker(记忆化搜索)

Description

A password locker with N digits, each digit can be rotated to 0-9 circularly.
You can rotate 1-3 consecutive digits up or down in one step.
For examples:
567890 → 567901 (by rotating the last 3 digits up)
000000 → 000900 (by rotating the 4th digit down)
Given the current state and the secret password, what is the minimum amount of steps you have
to rotate the locker in order to get from current state to the secret password?

Input

Multiple (less than 50) cases, process to EOF.
For each case, two strings with equal length (≤ 1000) consists of only digits are given, representing
the current state and the secret password, respectively.

Output

For each case, output one integer, the minimum amount of steps from the current state to the secret
password.

Sample Input

111111 222222
896521 183995

Sample Output

2
12

解析

一开始没考虑全面例如11322->00000,最少只需要三步,首先将113->002,然后将222->000,一共三步,没想到区间还可以交叉,于是一个劲的写,就把错误代码放在这里吧,毕竟也写了一个多小时。

我们定义状态方程dp[pos][a][b][c],其中pos表示字符串的位置,abc分别表示pos位置,pos+1位置pos+2位置对应的数字,也就是pos之前的数字全部都是正确的,我们只需要将pos位置的转到正确位置,然后向后搜索即可。

我们每一次通过向或者向下直接将pos位置的数字直接转到正确的数字,然后枚举pos+1pos+2位置的转动次数,就可以实现三个连续转动,两个连续转动,单个转动的枚举。(真是个神仙想法,可惜我还是看的网上的思路)

AC代码

#include <bits/stdc++.h>
using namespace std;

const int INF = 0x3f3f3f3f;
const int len = 10;
const int maxn = 1000 + 5;
int dp[maxn][len][len][len];
char pattern[maxn], text[maxn];
int length;

int dfs(const int &pos, const int &a, const int &b, const int &c)
{
    if(dp[pos][a][b][c] != -1)
        return dp[pos][a][b][c];

    if(pos >= length)
        return 0;


    int u_step = (text[pos] - '0' - a + len) % len;
    int d_step = (a - (text[pos] - '0') + len) % len;

    int res = INF;
    for(int i = 0; i <= u_step; i++)
        for(int j = 0; j <= i; j++)
            res = min(res, dfs(pos + 1, (b + i + len) % len, (c + j + len) % len, pattern[pos + 3] - '0') + u_step);

    for(int i = 0; i <= d_step; i++)
        for(int j = 0; j <= i; j++)
            res = min(res, dfs(pos + 1, (b - i + len) % len, (c - j + len) % len, pattern[pos + 3] - '0') + d_step);

    return dp[pos][a][b][c] = res;
}

int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
    while(scanf("%s %s", pattern, text) != EOF)
    {
        memset(dp, -1, sizeof dp);

        length = strlen(pattern);

        for(int i = 0; i <= 3; i++)
            text[length + i] = pattern[length + i] = '0';


        printf("%d\n", dfs(0, pattern[0] - '0', pattern[1] - '0', pattern[2] - '0'));
    }
    return 0;
}

没AC但是写了一个小时的破代码

#include <bits/stdc++.h>
using namespace std;

const int INF = 0x3f3f3f3f;
const int len = 10;
const int maxn = 1000 + 5;
char pattern[maxn], text[maxn];
int dp[maxn][maxn];

int dfs(const int &l, const int &r)
{
    if(l == r)
        return min((pattern[l] - text[l] + len) % len, (text[l] - pattern[l] + len) % len);

    if(dp[l][r] != -1)
        return dp[l][r];

    if(l + 1 == r)
    {
        int res = INF;

        char x = pattern[l], y = pattern[r];
        int step;

        for(char ch = '0'; ch <= '9'; ch++)
        {
            pattern[l] = ch;

            step = (ch - x + len) % len; //l u
            pattern[r] = (y - '0' + step + len) % len + '0';
            res = min(res, dfs(l, l) + dfs(r, r) + step);

            step = (x - ch + len) % len; //l d
            pattern[r] = (y - '0' - step + len) % len + '0';
            res = min(res, dfs(l, l) + dfs(r, r) + step);

            pattern[r] = ch;

            step = (ch - y + len) % len;//r u
            pattern[l] = (x - '0' + step + len) % len + '0';
            res = min(res, dfs(l, l) + dfs(r, r) + step);

            step = (y - ch + len) % len;//r d
            pattern[l] = (x - '0' - step + len) % len + '0';
            res = min(res, dfs(l, l) + dfs(r, r) + step);
        }

        pattern[l] = x, pattern[r] = y;

        return dp[l][r] = res;
    }

    if(l + 2 == r)
    {
        int res = INF;

        char x = pattern[l], y = pattern[l + 1], z = pattern[r];
        int step;

        for(char ch = '0'; ch <= '9'; ch++)
        {
            pattern[l] = ch;

            step = (ch - x + len) % len;//l u
            pattern[l + 1] = (y - '0' + step + len) % len + '0';
            pattern[r] = (z - '0' + step + len) % len + '0';
            res = min(res, dfs(l, l) + dfs(l + 1, r) + step);
            res = min(res, dfs(l, l + 1) + dfs(r, r) + step);
            res = min(res, dfs(l, l) + dfs(l + 1, l + 1) + dfs(r, r) + step);

            step = (x - ch + len) % len;//l d
            pattern[l + 1] = (y - '0' - step + len) % len + '0';
            pattern[r] = (z - '0' - step + len) % len + '0';
            res = min(res, dfs(l, l) + dfs(l + 1, r) + step);
            res = min(res, dfs(l, l + 1) + dfs(r, r) + step);
            res = min(res, dfs(l, l) + dfs(l + 1, l + 1) + dfs(r, r) + step);

            pattern[l + 1] = ch;

            step = (ch - y + len) % len;//m u
            pattern[l] = (x - '0' + step + len) % len + '0';
            pattern[r] = (z - '0' + step + len) % len + '0';
            res = min(res, dfs(l, l) + dfs(l + 1, r) + step);
            res = min(res, dfs(l, l + 1) + dfs(r, r) + step);
            res = min(res, dfs(l, l) + dfs(l + 1, l + 1) + dfs(r, r) + step);

            step = (y - ch + len) % len;//m d
            pattern[l] = (x - '0' - step + len) % len + '0';
            pattern[r] = (z - '0' - step + len) % len + '0';
            res = min(res, dfs(l, l) + dfs(l + 1, r) + step);
            res = min(res, dfs(l, l + 1) + dfs(r, r) + step);
            res = min(res, dfs(l, l) + dfs(l + 1, l + 1) + dfs(r, r) + step);

            pattern[r] = ch;

            step = (ch - z + len) % len;//r u
            pattern[l] = (x - '0' + step + len) % len + '0';
            pattern[l + 1] = (y - '0' + step + len) % len + '0';
            res = min(res, dfs(l, l) + dfs(l + 1, r) + step);
            res = min(res, dfs(l, l + 1) + dfs(r, r) + step);
            res = min(res, dfs(l, l) + dfs(l + 1, l + 1) + dfs(r, r) + step);

            step = (z - ch + len) % len;//r d
            pattern[l] = (x - '0' - step + len) % len + '0';
            pattern[l + 1] = (y - '0' - step + len) % len + '0';
            res = min(res, dfs(l, l) + dfs(l + 1, r) + step);
            res = min(res, dfs(l, l + 1) + dfs(r, r) + step);
            res = min(res, dfs(l, l) + dfs(l + 1, l + 1) + dfs(r, r) + step);
        }

        pattern[l] = x, pattern[l + 1] = y, pattern[r] = z;

        return dp[l][r] = res;
    }

    int res = INF;
    for(int i = l; i < r; i++)
        res = min(res, dfs(l, i) + dfs(i + 1, r));

    return dp[l][r] = res;
}

int main()
{
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);

    while(scanf("%s %s", pattern, text) != EOF)
    {
        memset(dp, -1, sizeof dp);

        printf("%d\n", dfs(0, strlen(pattern) - 1));
    }
    return 0;
}

发布了76 篇原创文章 · 获赞 18 · 访问量 2739

猜你喜欢

转载自blog.csdn.net/qq_43446165/article/details/104060255