被yobobobo的五十行代码给鄙视了!~写挫鸟~~
dp[i][j]表示前i个数字中前i-2个数字已经调换好了,第i-1个数字x和第i个数字y满足x*10+y=j对应状态的最小操作数,代码如下:
#include <cstdio> #include <cstring> #include <iostream> using namespace std; const int NN=1010; int r1[NN][NN],r2[NN][NN],r3[NN][NN]; int min3(int x,int y,int z) { int ret=x; if (y<ret) ret=y; if (z<ret) ret=z; return ret; } int fuck1(int x,int y)//一位数转变 { if (r1[x][y]!=-1) return r1[x][y]; if (x==y) return r1[x][y]=0; if (x>y) return r1[x][y]=r1[y][x]=min(x-y,10+y-x); else return r1[y][x]=r2[x][y]=min(y-x,10+x-y); } int fuck2(int x,int y)//两位数转变 { if (r2[x][y]!=-1) return r2[x][y]; if (x==y) return r2[x][y]=0; int a,b,tmp; int ret=fuck1(x/10,y/10)+fuck1(x%10,y%10); a=x; for (int i=1; i<=5; i++) { b=0; for (int k=1; k<=10; k*=10) if (a/k%10<9) b+=((a/k%10)+1)*k; a=b; tmp=fuck1(a/10,y/10)+fuck1(a%10,y%10); if (tmp+i<ret) ret=tmp+i; } for (int i=4; i>=1; i--) { b=0; for (int k=1; k<=10; k*=10) if (a/k%10<9) b+=((a/k%10)+1)*k; a=b; tmp=fuck1(a/10,y/10)+fuck1(a%10,y%10); if (tmp+i<ret) ret=tmp+i; } return r2[x][y]=r2[y][x]=ret; } int fuck3(int x,int y)//三位一起转变 { if (r3[x][y]!=-1) return r3[x][y]; if (x==y) return r3[x][y]=0; int a,b,tmp; int ret=min(fuck1(x/100,y/100)+fuck2(x%100,y%100),fuck2(x/10,y/10)+fuck1(x%10,y%10)); a=x; for (int i=1; i<=5; i++) { b=0; for (int k=1; k<=100; k*=10) if (a/k%10<9) b+=((a/k%10)+1)*k; a=b; tmp=min(fuck1(a/100,y/100)+fuck2(a%100,y%100),fuck2(a/10,y/10)+fuck1(a%10,y%10)); if (tmp+i<ret) ret=tmp+i; } for (int i=4; i>=1; i--) { b=0; for (int k=1; k<=100; k*=10) if (a/k%10<9) b+=((a/k%10)+1)*k; a=b; tmp=min(fuck1(a/100,y/100)+fuck2(a%100,y%100),fuck2(a/10,y/10)+fuck1(a%10,y%10)); if (tmp+i<ret) ret=tmp+i; } return r3[x][y]=r3[y][x]=ret; } int n,s1[NN],s2[NN],s3[NN],t1[NN],t2[NN],t3[NN],dp[NN][NN]; char s[NN],t[NN]; int main() { memset(r1,-1,sizeof(r1)); memset(r2,-1,sizeof(r2)); memset(r3,-1,sizeof(r3)); for (int i=0; i<=9; i++) for (int j=i; j<=9; j++) r1[i][j]=r1[j][i]=fuck1(i,j); for (int i=0; i<=99; i++) for (int j=i; j<=99; j++) r2[i][j]=r2[j][i]=fuck2(i,j); for (int i=0; i<=999; i++) for (int j=i; j<=999; j++) r3[i][j]=r3[j][i]=fuck3(i,j); while (scanf("%s%s",s,t)!=EOF) { n=strlen(s); s1[0]=s2[0]=s3[0]=s[0]-'0'; s1[1]=s[1]-'0'; s2[1]=s3[1]=(s[0]-'0')*10+s[1]-'0'; for (int i=2; i<n; i++) { s1[i]=s[i]-'0'; s2[i]=(s[i-1]-'0')*10+s1[i]; s3[i]=(s[i-2]-'0')*100+s2[i]; } t1[0]=t2[0]=t3[0]=t[0]-'0'; t1[1]=t[1]-'0'; t2[1]=t3[1]=(t[0]-'0')*10+t[1]-'0'; for (int i=2; i<n; i++) { t1[i]=t[i]-'0'; t2[i]=(t[i-1]-'0')*10+t1[i]; t3[i]=(t[i-2]-'0')*100+t2[i]; } if (n==1) { printf("%d\n",r1[s1[0]][t1[0]]); continue; } if (n==2) { printf("%d\n",r2[s2[1]][t2[1]]); continue; } if (n==3) { printf("%d\n",r3[s3[2]][t3[2]]); continue; } for (int i=0; i<=9; i++) dp[0][i]=r1[s1[0]][i]; for (int i=0; i<=99; i++) dp[1][i]=r2[s2[1]][i]; for (int i=0; i<=99; i++) dp[2][i]=r3[s3[2]][t1[0]*100+i]; for (int i=3; i<n; i++) for (int j=0; j<=99; j++) { dp[i][j]=min3(dp[i-1][t1[i-2]*10+j/10]+r1[s1[i]][j%10], dp[i-2][t2[i-2]] +r2[s2[i]][j], dp[i-3][t2[i-3]] +r3[s3[i]][t1[i-2]*100+j]); for (int k=0; k<=9; k++) { dp[i][j]=min(dp[i][j],dp[i-1][t1[i-2]*10+k]+r2[k*10+s1[i]][j]); dp[i][j]=min(dp[i][j],dp[i-2][t1[i-3]*10+k]+r3[k*100+s2[i]][t1[i-2]*100+j]); } for (int k=0; k<=99; k++) { dp[i][j]=min(dp[i][j],dp[i-1][k]+r3[k*10+s1[i]][t1[i-2]*100+j]); } } printf("%d\n",dp[n-1][t2[n-1]]); } return 0; }