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

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