UVA-1631 Locker(DP)

A password locker withN 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 haveto 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 secretpassword.

Sample Input

111111 222222
896521 183995

Sample Output

212 

题意:

给你两串数字,类似于密码锁的机制,每次可以转1-3位连续的数字,数字为0-9,循环旋转。问你最少转几次能让第一串等于第二串。

分析:

DP,但是DP的方法好像因人而异,调不出错的时候去网上看了几份题解,发现自己DP有点非主流……

dp函数有3个参数,第一个参数x表示目前正在转哪一位(从右往左转),第二参数r1和第三参数r2表示处理第x+1位时,对第x位和第x-1位的旋转的次数。

然后通过dp方程转啊转啊就可以了……

开头想简单了,认为要往最近的方向转,实际上有时候远的那一方才是正确答案,然后强行修改了,仔细想想还能精简很多。

#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
#define INF 0x3f3f3f3f
const int N=10005;
const int mod=1e9+7;

string s1,s2;
int d[1005][10][10];

int dp(int x,int r1,int r2) {
    r1=(r1+10)%10;
    r2=(r2+10)%10;
    
    if (d[x][r1][r2]!=-1) return d[x][r1][r2];
    int n1=(s1[x]-'0'+r1)%10;
    int n2=s2[x]-'0',minn=0;
    if (n1<n2) {
        minn=n2-n1;
        if (n1+10-n2<minn)  minn=n2-n1-10;
    } else {
        minn=n2-n1;
        if (n1-n2-10>minn) minn=n2-n1+10;
    }
    if (x==0) {
        d[x][r1][r2]=abs(minn);
        return d[x][r1][r2]=abs(minn);
    }
    int temp1=INF,temp2=INF;
    if (minn>=0) {
        for (int i=0; i<=minn; i++) {
            for (int j=0; j<=i; j++) {
                temp1=min(temp1, dp(x-1, r2+i, j));
            }
        }
        for (int i=0; i>=minn-10; i--) {
            for (int j=0; j>=i; j--) {
                temp2=min(temp2, dp(x-1, r2+i, j));
            }
        }
    } else {
        for (int i=0; i>=minn; i--) {
            for (int j=0; j>=i; j--) {
                temp1=min(temp1, dp(x-1, r2+i, j));
            }
        }
        for (int i=0; i<=minn+10; i++) {
            for (int j=0; j<=i; j++) {
                temp2=min(temp2, dp(x-1, r2+i, j));
            }
        }
    }
    d[x][r1][r2]=min(abs(minn)+temp1, 10-abs(minn)+temp2);
    return d[x][r1][r2];
}

int main() {
    while (cin>>s1>>s2) {
        int len=s1.length();
        memset(d, -1, sizeof(d));
        cout<<dp(len-1, 0, 0)<<endl;
    }
    return 0;
}

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