HDU 4433 locker

题意: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?
 #include <iostream>
 #include <string>
 #include <cstring>
 #include <cstdio>
 #define maxn 1100
 #define inf 1000000
 using namespace std;

 char s1[maxn];
 char s2[maxn];
 int   a[maxn];
 int   b[maxn];
 int up[12][12];
 int down[12][12];
 int dp[maxn][12][12];
 int n;

 void init()
 {
     int i,j;
     for(i=0;i<=9;i++)
     {
         for(j=0;j<=9;j++)
         {
             up[i][j]=j>=i?j-i:10+(j-i);
             down[i][j]=j<=i?i-j:10+i-j;
         }
     }
 }

 int main()
 {
     init();
     int i,j,k;
     int ii,jj;
     while(~scanf("%s %s",&s1, &s2))
     {
         n = strlen(s1);
         for(i=0;i<=n+3;i++)
         {
             for(j=0;j<=9;j++)
             {
                 for(k=0;k<=9;k++)
                 {
                     dp[i][j][k]=inf;
                 }
             }
         }

         for(i=0; i<n; i++)
         {
             a[i] = s1[i]-'0';
             b[i] = s2[i]-'0';
         }
         a[i] = a[i+1] = b[i] = b[i+1] = 0;
         dp[0][a[0]][a[1]]=0;

         for(i=1; i<=n; i++)
         {
             for(j=0; j<=9; j++)
             {
                 for(k=0; k<=9; k++)
                 {
                     int temp=up[j][b[i-1]];
                     for(ii=0; ii<=temp; ii++)
                     {
                         for(jj=0; jj<=ii; jj++)
                         {
                             dp[i][(k+ii)%10][(a[i+1]+jj)%10]=
                             min(dp[i][(k+ii)%10][(a[i+1]+jj)%10],dp[i-1][j][k]+temp);
                         }
                     }

                     temp=down[j][b[i-1]];
                     for(ii=0;ii<=temp;ii++)
                     {
                         for(jj=0;jj<=ii;jj++)
                         {
                             dp[i][(k-ii+10)%10][(a[i+1]-jj+10)%10]=
                             min(dp[i][(k-ii+10)%10][(a[i+1]-jj+10)%10],dp[i-1][j][k]+temp);
                         }
                     }
                 }
             }
         }
         printf("%d\n",dp[n][0][0]);
     }
     return 0;
 }

 

posted @ 2012-10-28 19:12  'wind  阅读(504)  评论(0编辑  收藏  举报