链接:点击打开链接
题意:给两个等长的字符串,每次最多可以旋转连续的三个数字,注意0可以旋转到9,问最少需要多少次才能将S串变为T串
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
char s1[1005],s2[1005];
int a[1005],b[1005],dp[1005][15][15];
int main(){ //dp[i][j][k]表示i为之前已经转完,i+1为j,i+2为k
int i,j,k,p,q,n,m,len,up,down;
while(scanf("%s%s",s1+1,s2+1)!=EOF){
len=strlen(s1+1);
a[0]=b[0]=0;
a[len+1]=a[len+2]=0;
b[len+1]=b[len+2]=0;
for(i=1;i<=len;i++){
a[i]=s1[i]-'0';
b[i]=s2[i]-'0';
}
memset(dp,INF,sizeof(dp));
dp[0][a[1]][a[2]]=0;
for(i=1;i<=len;i++){
for(j=0;j<10;j++){
for(k=0;k<10;k++){
if(dp[i-1][j][k]==INF)
continue;
down=(b[i]-j+10)%10; //枚举后两位转动的次数,后两位的次数一定小于当前位
for(p=0;p<=down;p++) //一次向后,一次向前
for(q=0;q<=p;q++)
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);
up=10-down;
for(p=0;p<=up;p++)
for(q=0;q<=p;q++)
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);
}
}
}
printf("%d\n",dp[len][0][0]);
}
return 0;
}