题意:
有2个数字串,每次可以变化1-3位(每位+1或-1(0-9,9-0)可循环),求由1串变到2串的最小用的次数。
分析:
dp[i][num]表示变到第i位时最后两位组成的数是num时最小次数(因为dp[i-1][num1],num1肯定是i位数的i-1,i-2位数,dp[i][num]=min(dp[i-1][num1]+cost[p][q])cost[p][q]表示(p,q后三位数字最小转化次数,可以预处理,要细心)
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <string> #include <cctype> #include <complex> #include <cassert> #include <utility> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; typedef pair<int,int> PII; typedef long long ll; #define lson l,m,rt<<1 #define pi acos(-1.0) #define rson m+1,r,rt<<11 #define All 1,N,1 #define read freopen("in.txt", "r", stdin) const ll INFll = 0x3f3f3f3f3f3f3f3fLL; const int INF= 0x7ffffff; const int mod = 1000000007; int dp[2][110],cost[1010][1010],n; char a[1010],b[1010]; void init(){ for(int i=0;i<1000;++i) for(int j=0;j<1000;++j){ if(i==j)continue; if(cost[i][j]!=0)continue; int p1=i/100; int p2=(i/10)%10; int p3=i%10; int q1=j/100; int q2=(j/10)%10; int q3=j%10; int u1,u2,u3; if(p1<q1){ u1=q1-p1; p2=(p2+u1)%10; p3=(p3+u1)%10; } else{ u1=p1-q1; p2=(p2-u1+10)%10; p3=(p3-u1+10)%10; } if(p2<q2){ u2=q2-p2; p3=(p3+u2)%10; } else{ u2=p2-q2; p3=(p3-u2+10)%10; } u3=p3>q3?p3-q3:q3-p3; u1=u1>10-u1?10-u1:u1; u2=u2>10-u2?10-u2:u2; u3=u3>10-u3?10-u3:u3; cost[i][j]=cost[j][i]=u1+u2+u3; } } void solve(){ for(int i=0;i<10;++i){ int id=a[1]-'0'; int tmp=i>id?i-id:id-i; dp[0][i]=(tmp>10-tmp)?10-tmp:tmp; } for(int i=0;i<100;++i){ int minv=INF; for(int j=0;j<10;++j){ int q=a[2]-'0'+j*10; minv=min(minv,dp[0][j]+cost[i][q]); } dp[1][i]=minv; } int now=1; for(int i=3;i<=n;++i){ now^=1; for(int j=0;j<100;++j) { int minv=INF; for(int k=0;k<100;++k){ int p=(b[i-2]-'0')*100+j; int q=10*k+(a[i]-'0'); minv=min(minv,dp[now^1][k]+cost[p][q]); } dp[now][j]=minv; } } int num=10*(b[n-1]-'0')+(b[n]-'0'); printf("%d\n",dp[now][num]); } int main() { init(); while(scanf("%s%s",a+1,b+1)==2){ n=strlen(a+1); if(n==1) { int m=a[1]>b[1]?a[1]-b[1]:b[1]-a[1]; printf("%d\n",m>10-m?10-m:m); } else{ solve(); } } return 0; }