比赛的时候遇到的题,不会做
赛后看别人的代码才知道怎么做
用dp[i][j][k]表示两个字符串前i位已经匹配,且完成这个操作后对第i+1位改变了j,对i+2位改变了k
那么我们可以知道对第i+2的操作数小于等于对第i+1位的操作数小于等于对第i位的操作数
然后暴力枚举所有状态。。。
代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXN 1010
using namespace std;
char s1[MAXN], s2[MAXN];
int dp[MAXN][10][10];
int main(void) {
while(~scanf("%s%s", s1, s2)) {
int len = strlen(s1);
memset(dp, 0x3f, sizeof(dp));
dp[0][0][0] = 0;
for(int i=0; i<len; ++i) {
for(int j=0; j<10; ++j) {
for(int k=0; k<10; ++k) {
int a = (s2[i]-s1[i]+20-j)%10;
for(int b=0; b<=a; ++b) {
for(int c=0; c<=b; ++c) {
dp[i+1][(k+b)%10][c] = min(dp[i+1][(k+b)%10][c], dp[i][j][k]+a);
}
}
a = (10-a)%10;
for(int b=0; b<=a; ++b) {
for(int c=0; c<=b; ++c) {
dp[i+1][(k-b+10)%10][(10-c)%10] = min(dp[i+1][(k-b+10)%10][(10-c)%10], dp[i][j][k]+a);
}
}
}
}
}
printf("%d\n", dp[len][0][0]);
}
return 0;
}