hdu4433 locker

locker

Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 880 Accepted Submission(s): 371


Problem 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

Source
2012 Asia Tianjin Regional Contest
唉,当时,打比赛的时候,只用了dp[i]推到dp[i+1],测试都没通过,但我们只能举出小数据,不能验证对错,反正一直wrong到了最后,后来看了解题报告,才发现,我们忽略了第i位的地后面两位的影响,因为,你想,如果,我们在换第i位时候,肯定也可以把第i+1,i+2,也顺手更换几次,但不一定变换同样多的次数,这样得用三位才能转移壮态,要不然,我们先前的没用考虑第i+1,I+2位,那么自然,会多出很多的步数来,这一点,当时就是没想通!,也就是dp[i][j][k]表示更新第i位完全匹配,第i+1位改变了j个,第i+2位改变了k个,那么k>=j>=第i位的变化量!剩下的就很简单了!
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
#define inf 10000000
int fmin(int a,int b){if(a<b)return a;return b;}
int dp[1005][10][10],strnum;char start[1005],end[1005];
int main()
{
    int i,j,k,m,n,temp;
    while(scanf("%s%s",start,end)!=EOF)
    {
        strnum=strlen(start);
        for(i=0;i<=strnum;i++)
            for(j=0;j<10;j++)
                for(k=0;k<10;k++)
                    dp[i][j][k]=inf;
        dp[0][0][0]=0;
        for(i=0;i<strnum;i++)
            for(j=0;j<10;j++)
                for(k=0;k<10;k++)
                {
                    temp=((end[i]-start[i])-j+20)%10;
                    for(m=0;m<=temp;m++)
                        for(n=0;n<=m;n++)
                        dp[i+1][(k+m)%10][n]=fmin(dp[i+1][(k+m)%10][n],dp[i][j][k]+temp);
                    temp=(10-temp)%10;
                    for(m=0;m<=temp;m++)
                        for(n=0;n<=m;n++)
                        dp[i+1][(k-m+10)%10][(10-n)%10]=fmin( dp[i+1][(k-m+10)%10][(10-n)%10],dp[i][j][k]+temp);
                }
        printf("%d\n",dp[strnum][0][0]);
    }
    return 0;
}

你可能感兴趣的:(hdu4433 locker)