题意:给你个长度为n的数字串,每次最多旋转三个数字,至少经过都少部才能到达目标串。
思路:一开始我也是用DP做的,但是没考虑到后效性,所以wa了。后来看了题解,思路是这样的dp[i][j][k]表示第i为匹配好,第i+1位增加了j,第i+2增加了k。状态转移:第i+2位增加k+x,第i+3位增加y,然后还要考虑到减的情况。
代码如下:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<stdio.h>
#include<math.h>
#define N 1005
#define inf 0x7ffffff
#define eps 1e-9
#define pi acos(-1.0)
using namespace std;
char a[N],b[N];
int dp[N][15][15];
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
while(scanf("%s%s",a,b) != EOF)
{
int i,j,k;
int n = strlen(a);
for(i = 0; i <= n; i++)
for(j = 0; j < 10; j++)
for(k = 0; k < 10; k++)
dp[i][j][k] = inf;
dp[0][0][0] = 0;
for(i = 0; i < n; i++)
for(j = 0; j < 10; j++)
for(k = 0; k < 10; k++)
if(dp[i][j][k] != inf)
{
int x,y;
int t = (b[i] - a[i] - j + 20)%10;
for(x = 0; x <= t; x++)
for(y = 0; y <= x; y++)
dp[i+1][(k+x)%10][y] = min(dp[i+1][(k+x)%10][y], dp[i][j][k]+t);
t = (10-t);
for(x = 0; x <= t; x++)
for(y = 0; y <= x; y++)
dp[i+1][(k-x+10)%10][(10-y)%10] = min(dp[i+1][(k-x+10)%10][(10-y)%10], dp[i][j][k]+t);
}
printf("%d\n",dp[n][0][0]);
}
return 0;
}