博客园 首页 私信博主 显示目录 隐藏目录 管理

locker(dp) HDU - 4433

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?

InputMultiple (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.
OutputFor 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
题意:给两个等长的字符串,每次最多可以旋转连续的三个数字,注意0可以旋转到9,问最少需要多少次才能将S串变为T串
分析:看到题目很自然的能够想到dp,我们可以假设dp(i,j,k)表示第i个位置及其之前的位置已经和目的数字相同,第i+1个位置为j,第i+2个位置为k
例如:我们假设dp(i-1,j,k)表示前i-1个位置(包括第i-1个位置)已经和目的数字相同,第i个位置为j,第i+1个位置为k,我们从0~9枚举j,k,在这里有两种情况
:上升枚举或者下降枚举,另外,注意在状态转移的过程中,第2个位置转换次数要小于第1个位置的转换次数。
则状态转移方程为:
升序枚举:dp[i][(k-p+10)%10][(a[i+2]-q+10)%10]=min(dp[i][(k-p+10)%10][(a[i+2]-q+10)%10],dp[i-1][j][k]+up);
降序枚举:dp[i][(k+p)%10][(a[i+2]+q)%10]=min(dp[i][(k+p)%10][(a[i+2]+q)%10],dp[i-1][j][k]+down);
 
AC代码:
 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 using namespace std;
 6 const int maxn = 1e3+10;
 7 #define LL long long
 8 #define INF 0x3f3f3f3f
 9 char s1[maxn],s2[maxn];
10 int a[maxn],b[maxn];
11 int dp[maxn][10][10];
12 
13 
14 int main(){
15     int i,j,k,p,q,n,m,len,up,down;
16     while(~scanf("%s%s",s1+1,s2+1)){
17         len=strlen(s1+1);
18         a[0]=b[0]=0;
19         a[len+1]=a[len+2]=0;
20         b[len+1]=b[len+2]=0;
21         for(int i=1;i<=len;i++){
22             a[i]=s1[i]-'0';
23             b[i]=s2[i]-'0';
24         }
25         memset(dp,INF,sizeof(dp));
26         dp[0][a[1]][a[2]]=0;
27         for(int i=1;i<=len;i++){
28             for(int j=0;j<10;j++){
29                 for(int k=0;k<10;k++){
30                     if(dp[i-1][j][k]==INF) continue;
31                     down=(b[i]-j+10)%10;
32                     for(p=0;p<=down;p++) for(q=0;q<=p;q++){
33                         dp[i][(k+p)%10][(a[i+2]+q)%10]=min(dp[i][(k+p)%10][(a[i+2]+q)%10],dp[i-1][j][k]+down);
34                     }
35                     up=10-down;
36                     for(p=0;p<=up;p++) for(q=0;q<=p;q++){
37                         dp[i][(k-p+10)%10][(a[i+2]-q+10)%10]=min(dp[i][(k-p+10)%10][(a[i+2]-q+10)%10],dp[i-1][j][k]+up);
38                     }
39                 }
40             }
41         }
42         printf("%d\n",dp[len][0][0]);
43     }
44 
45 
46 
47     return 0;
48 }
49 /*
50 111111 222222
51 896521 183995
52 */

 

 
posted @ 2019-08-16 15:11  Brave_WTZ  阅读(154)  评论(0编辑  收藏  举报