Locker

时间:2025-02-25 10:06:56

题意:

有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 = ;
int dp[][],cost[][],n;
char a[],b[];
void init(){
for(int i=;i<;++i)
for(int j=;j<;++j){
if(i==j)continue;
if(cost[i][j]!=)continue;
int p1=i/;
int p2=(i/)%;
int p3=i%;
int q1=j/;
int q2=(j/)%;
int q3=j%;
int u1,u2,u3;
if(p1<q1){
u1=q1-p1;
p2=(p2+u1)%;
p3=(p3+u1)%;
}
else{
u1=p1-q1;
p2=(p2-u1+)%;
p3=(p3-u1+)%;
}
if(p2<q2){
u2=q2-p2;
p3=(p3+u2)%;
}
else{
u2=p2-q2;
p3=(p3-u2+)%;
}
u3=p3>q3?p3-q3:q3-p3;
u1=u1>-u1?-u1:u1;
u2=u2>-u2?-u2:u2;
u3=u3>-u3?-u3:u3;
cost[i][j]=cost[j][i]=u1+u2+u3;
}
}
void solve(){
for(int i=;i<;++i){
int id=a[]-'';
int tmp=i>id?i-id:id-i;
dp[][i]=(tmp>-tmp)?-tmp:tmp;
}
for(int i=;i<;++i){
int minv=INF;
for(int j=;j<;++j){
int q=a[]-''+j*;
minv=min(minv,dp[][j]+cost[i][q]);
}
dp[][i]=minv;
}
int now=;
for(int i=;i<=n;++i){
now^=;
for(int j=;j<;++j)
{
int minv=INF;
for(int k=;k<;++k){
int p=(b[i-]-'')*+j;
int q=*k+(a[i]-'');
minv=min(minv,dp[now^][k]+cost[p][q]);
}
dp[now][j]=minv;
}
}
int num=*(b[n-]-'')+(b[n]-'');
printf("%d\n",dp[now][num]);
}
int main()
{
init();
while(scanf("%s%s",a+,b+)==){
n=strlen(a+);
if(n==)
{
int m=a[]>b[]?a[]-b[]:b[]-a[];
printf("%d\n",m>-m?-m:m);
}
else{
solve();
}
}
return ;
}