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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章